You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为已渲染的Web Component绑定handleDelete方法

Web Component绑定handleDelete方法的问题

我在为Web Component绑定handleDelete方法时遇到了困难。当前流程是:用户点击加号按钮后,数据对象会存储在window对象的数组中,随后调用SelectedProducts组件的render方法,渲染出带有待绑定handleDelete方法按钮的卡片。我希望不借助第三方库完成,同时仍在困惑需使用哪些生命周期方法或是否需要自定义事件。

代码实现

JavaScript代码

class SelectedProducts extends HTMLElement {
  constructor() {
    super();
    this.mockData = [
      { id: 1, name: 'name-1', qty: 1 },
      { id: 2, name: 'name-2', qty: 1 },
      { id: 2, name: 'name-1', qty: 2 },
    ];
  }
  handleDelete(e) {
    e.preventDefault();
    console.log('called handleDelete');
  }

  connectedCallback() {
    this.querySelector('button').addEventListener('click', this.handleDelete.bind(this));
  }

  attributeChangedCallback(attrName, oldValue, newValue) {
    console.log('attributeChange called');
    this.handleDelete(e);
  }

  static get observedAttributes() {
    return ['data-id'];
  }

  disconnectedCallback() {
    console.log('disconnectedCallback ran');
  }

  render() {
    this.mockData.forEach((item, index) => {
      this.innerHTML += `
      <div style="display:flex; align-items: center; background-color:white; padding:15px; ">
        <button data-id="${item.id}" class="delete-btn">
          Delete me
        </button>
      </div>
      `;
    });
  }

  handleDelete(e) {
    e.preventDefault();
    alert('Called Handle delete');
  }
}
customElements.define('selected-products', SelectedProducts);

class ProductCard extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({
      mode: 'open',
    });

    this.shadowRoot.innerHTML =
      `<style>
      ::slotted(div){
        color: #4B5563; 
        font-weight: 900; 
        text-align: center; 
        font-size: 20px; 
      }
      </style>
      ` +
      ` <div style="background: white; margin-right: 15px;">
          <slot name="button"></slot>
          <slot name="img"></slot>
        </div>
      `;
  }
}

customElements.define('product-card', ProductCard);

class SelectBtn extends HTMLElement {
  constructor() {
    super();
    // This is called with render below
    this.itemsPicked = document.querySelector('selected-products');
    this.attachShadow({
      mode: 'open',
    });
    this.shadowRoot.innerHTML = `
    <button
    aria-label="Select"
    type="button"
    class="pressed"
    data-addbtn="add-btn"
  >
   +
  </button>
    
    `;

    this.id = this.getAttribute('id');
    this.name = this.getAttribute('name');
    this.shadowRoot
      .querySelectorAll('button')
      .forEach((button) => button.addEventListener('click', this.handleSelect.bind(this)));
  }
  // Get data from attributes & store object in
  // an array on window object
  handleSelect(e) {
    e.preventDefault();
    this.itemsPicked.render();
  }
}

customElements.define('select-button', SelectBtn);

HTML代码

<body>
    <div style="display: flex; justify-content: center; align-items: center; background: lightblue; padding: 10px">
      <product-card>
        <div slot="button">
          <select-button id="1" name="product name"></select-button>
        </div>
        <div slot="img">
          <div style="height: 100px; width: 100px">Select Button</div>
        </div>
      </product-card>
      <div>
        <selected-products></selected-products>
      </div>
    </div>
    <script src="app.js"></script>
    <script>
      window.selectedItems = {
        items: [],
      };
    </script>
  </body>

内容的提问来源于stack exchange,提问作者Mike Haslam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 09:31:02