Совместно использовать один и тот же теневой DOM между несколькими теневыми хостами? - PullRequest
0 голосов
/ 09 марта 2019

Я просто открываю веб-компоненты и пока не уверен, что это хорошо поняли.

Но вот мой вопрос.Кажется, у этого есть много преимуществ.Я хотел бы знать, возможно ли использовать один и тот же теневой DOM на нескольких теневых хостах?

Мне нужно несколько экземпляров элемента на моей веб-странице.
Если (один) теневой DOMобновлено, все экземпляры будут обновляться слишком автоматически.

Является ли это одним из применений теневого DOM;и как мне этого добиться?

Спасибо!

1 Ответ

0 голосов
/ 12 марта 2019

Этого же эффекта можно добиться, если иметь содержащий компонент, который прослушивает событие при изменении свойства и передает значение дочерним компонентам.Таким образом, вы не разделяете сам экземпляр теневого DOM, но повторно используете компонент без дублирования кода.

class XContainer extends HTMLElement {
  constructor() {
    super();
    
    this.total = 0;
  }
  
  connectedCallback() {    
    this.addEventListener('x-increment', this.onIncrement);
    
    this.onIncrement = this.onIncrement.bind(this);
  }
  
  onIncrement(event) {
    this.total = this.total + event.detail.amount;
    
    this.querySelectorAll('x-counter').forEach((counterEl) => {
      counterEl.total = this.total;
    });
  }
}
customElements.define('x-container', XContainer);


class XControls extends HTMLElement {
  constructor() {
    super();
    
    this.attachShadow({ mode: 'open' });
    
    this.shadowRoot.innerHTML = `
      <button>+</button>
    `;
  }
    
  connectedCallback() {    
    this.shadowRoot.querySelector('button').addEventListener('click', this.onClick);
    
    this.onClick = this.onClick.bind(this);
  }
  
  onClick(event) {
    this.dispatchEvent(new CustomEvent('x-increment', {
      bubbles: true,
      composed: true,
      detail: {
        amount: 1,
      }
    }));
  }
}
customElements.define('x-controls', XControls);


class XCounter extends HTMLElement {
  constructor() {
    super();
  
    this.attachShadow({ mode: 'open' });
    
    this.shadowRoot.innerHTML = `
      <h2>Total: <span>0</span>
    `;
  }
  
  set total(value) {
    this.shadowRoot.querySelector('span').innerText = value;
  }
}
customElements.define('x-counter', XCounter);
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Web Component 101</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>  
  <body>

    <x-container>
      <x-counter></x-counter>
      <hr>
      <x-counter></x-counter>
      <hr>
      <x-controls></x-controls>
    </x-container>
    
  </body>
</html>
...