Lit-Element: какое событие использовать для обновлений DOM? - PullRequest
0 голосов
/ 21 ноября 2018

В документации по github.com / Polymer / lit-element описывается жизненный цикл, если свойство какого-либо освещенного элемента изменяется.Тем не менее, я не могу найти какую-либо документацию о жизненном цикле, если содержимое DOM элемента изменено.

Итак, предположим, у меня есть некоторая вложенная структура DOM, и мой самый внешний элемент должен отображать что-то на основе содержимого DOM.Для простоты в приведенном ниже примере будет просто отображаться количество дочерних элементов данного типа.

Теперь в какой-то момент мое приложение вставляет новый вложенный элемент (нажмите кнопку test ниже).На данный момент я хотел бы обновить показанное количество.

Из моих тестов кажется, что render() не вызывается снова в этом случае, равно как и updated().

Какое событие мне нужно прослушать или какую функцию мне нужно реализовать, чтобы распознать такое изменение?

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

  document.querySelector( 'button' )
          .addEventListener( 'click', () => {
            const el = document.querySelector( 'my-element' );
            el.insertAdjacentHTML( 'beforeend', '<my-nested-element>new addition</my-nested-element>' );
          })
my-element, my-nested-element {
  display: block;
}
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@latest/webcomponents-loader.js"></script>

<!-- Works only on browsers that support Javascript modules like Chrome, Safari, Firefox 60, Edge 17 -->
<script type="module">
  import {LitElement, html} from 'https://unpkg.com/@polymer/lit-element/lit-element.js?module';

  class MyElement extends LitElement {
    constructor(){
      super();
      this.number = this.querySelectorAll( 'my-nested-element' ).length;
    }
  
    render() {
      return html`<p>number of my-nested-element: ${this.number}</p> 
                  <slot></slot>`;
    }  
  }
  customElements.define('my-element', MyElement);
  
	class MyNestedElement extends LitElement {
    render() {
      return html`<slot></slot>`;
    }  
  }
  customElements.define('my-nested-element', MyNestedElement);
</script>

<my-element>
  <my-nested-element>first</my-nested-element>
  <my-nested-element>second</my-nested-element>
</my-element>

<button>test</button>

1 Ответ

0 голосов
/ 22 ноября 2018

Чтобы обнаружить новый элемент, вставленный из Light DOM через элемент <slot>, вы можете прослушивать slotchange события в элементе <slot> или в самом корне Shadow DOM.

См. Рабочий пример ниже:

document.querySelector('button').onclick = () => 
  document.querySelector('my-element').insertAdjacentHTML('beforeend', '<my-nested-element>new addition</my-nested-element>');
  
my-element,
my-nested-element {
  display: block;
}
<script type="module">
  import {LitElement, html} from 'https://unpkg.com/@polymer/lit-element/lit-element.js?module';

  class MyElement extends LitElement {
    firstUpdated() {
      var shadow = this.shadowRoot
      var nb = shadow.querySelector( 'span#nb' )
      shadow.addEventListener( 'slotchange', () => 
        nb.textContent = this.querySelectorAll( 'my-nested-element').length 
      )    
    }
    render() {
      return html`<p>number of my-nested-element: <span id="nb"></span></p> 
                  <slot></slot>`;
    }  
  }
  customElements.define('my-element', MyElement);
</script>

<my-element>
  <my-nested-element>first</my-nested-element>
  <my-nested-element>second</my-nested-element>
</my-element>

<button>test</button>
...