1

我是 hyperHTML 的新手,正在试验它。这是我的问题。如何为重复的模板元素添加事件处理程序。这是我的网络组件:

import css from './component.css';
import isJson from '../utils/isJson.js';
const hyper = hyperHTML;

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

  attributeChangedCallback(name, oVal, nVal) {
    if (name === 'tabs' && isJson(nVal)) {
      this.tabs = JSON.parse(nVal);
      this.tabs.forEach((tab) => {
        tab.number = parseInt(tab.number, 10).toLocaleString();
      });
      this.updateView();
    }
  }

  clearSelections() {
    this.tabs.forEach((tab) => {
      tab.selected = false;
    });
  }

  connectedCallback() {
    this.updateView();
  }

  currentlySelected() {
    return this.tabs.find((tab) => tab.selected);
  }

  disconnectedCallback() {
    
  }

  tabSelected(evn) {
   
  }

  updateView() {
    hyper(this.shadowRoot)`
      <style>${css}</style>
      <div id="tab-container">
      ${this.tabs.map(tab => `
        <div class="${tab.selected ? 'selected' : ''}" id="${tab.id}" onclick="${this.selectedTab}">
          <div class="name">${tab.name}</div>
          <div class="number">${tab.number}</div>
        </div>
      `)}
      </div>
      `;
  }

  static get observedAttributes() {
    return ['tabs'];
  }
}

customElements.define('idx-admin-tab', IdxAdminTab);

export { IdxAdminTab };

我想在重复选项卡中添加一个单击处理程序并将 tabSelected 注册为处理程序。我添加的点击处理程序引发了一个未捕获的语法错误:

(function(event){[object HTMLElement]
})

4

2 回答 2

2

您的代码有两个小问题:

  1. 如前所述,您只返回一个字符串
  2. 你没有绑定你的处理程序

当您使用模板文字时,很容易忘记它们只是字符串。您需要返回应该始终指向同一个选项卡的 DOM 节点(或连线)。

我假设tab.id它们是唯一的,并且我将它们用作绑定到组件本身的标识符。这是一个更好的版本:

class IdxAdminTab extends HTMLElement {
  constructor() {
    super();
    this.selectedTab = this.selectedTab.bind(this);
    this.render = hyper(this.attachShadow({mode: 'open'}));
    this.updateView();
  }

  selectedTab(e) {
    console.log('tab selected');
  }

  updateView() {
    this.render`
      <style>${css}</style>
      <div id="tab-container">
      ${this.tabs.map(tab => hyper(this, `:${tab.id}`)`
        <div class="${tab.selected ? 'selected' : ''}" id="${tab.id}" onclick="${this.selectedTab}">
          <div class="name">${tab.name}</div>
          <div class="number">${tab.number}</div>
        </div>
      `)}
      </div>`;
  }

}

如您所见,您甚至可以{mode: 'closed'}在将 shadowRoot 分配一次作为渲染属性时使用。

现在您有了一个完全正常工作的组件。

但是,hyperHTML 带有一个名为HyperHTMLElement的自定义元素助手,看看它的实用程序,也许它会让你的生活更轻松。

于 2017-10-17T21:09:16.780 回答
1

您的地图返回纯字符串,因此您的单击处理程序不指向函数,而是指向函数的字符串表示形式。

      ${this.tabs.map(tab => `
        <div class="${tab.selected ? 'selected' : ''}" id="${tab.id}" onclick="${this.selectedTab}">
          <div class="name">${tab.name}</div>
          <div class="number">${tab.number}</div>
        </div>
      `)}

利用

hyperHTML.wire(tab)`<div>...</div>`  

反而。代码笔

于 2017-10-13T20:06:28.963 回答