пользовательские элементы & connectedCallback (): дождитесь доступности родительского узла, прежде чем запускать функцию - PullRequest
1 голос
/ 12 октября 2019

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

Когда вызывается функция connectedCallback () , кажется, что узел еще не на своем месте в DOM, поэтому я не могу получить доступ к его родителям- и они мне нужны.

class myElement extends HTMLElement{
    constructor() {
        super();
        this.tracklist =    undefined;
    }
    connectedCallback(){
        this.render();
    }
    render(){

        this.tracklist = this.closest('section');

        // following code requires this.tracklist!
        // ...
    }

window.customElements.define('my-element', myElement);

Как я могу быть уверен, что родительские узлы доступны перед вызовом render ()?

Спасибо!

Ответы [ 2 ]

1 голос
/ 13 октября 2019

Это известная проблема:

connectedCallback делает не означает, что ваш элемент проанализирован или не полностью проанализирован.
В пользовательских элементах отсутствует метод parsedCallback

См. Все ответы по адресу:

TL; DR;

Может быть, быстро(и грязно?) Исправлена ​​ошибка, из-за которой задерживался ваш метод рендеринга:

 connectedCallback(){
     setTimeout(this.render);
 }
0 голосов
/ 12 октября 2019

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

Способ сделать это - изменить метод render для получения аргумента, который будет динамически устанавливать свойство tracklistк пользовательскому элементу. Затем выберите элемент my-element в DOM и найдите section.

. Затем используйте метод customElements.whenDefined, чтобы соединить section и my-element вместе всякий раз, когдаПользовательский элемент готов. Этот метод возвращает Обещание, которое разрешается всякий раз, когда определяется пользовательский элемент, и дает вам возможность выполнить обратный вызов.

См. Пример ниже:

// Do something whenever the element is ready.
window.addEventListener('load', function() {

  // Wait for the document to load so the DOM has been parsed.
  window.customElements.whenDefined('my-element').then(() => {
    const myElement = document.querySelector('my-element');

    // Only do something if the element exists on the page.
    if (myElement !== null) {
      const tracklist = myElement.closest('section');
      myElement.render(tracklist);
      console.log(myElement.tracklist);
    }

  });

});

// Create element.
class myElement extends HTMLElement{
    constructor() {
        super();
        this.tracklist = null;
    }
    render(tracklist){
        this.tracklist = tracklist;
        // following code requires this.tracklist!
        // ...
    }
}

// Define element.
window.customElements.define('my-element', myElement);
<section>
  <my-element></my-element>
</section>

Если у меня возникли вопросы или у вас есть вопросы, пожалуйста, дайте мне знать.

Хорошего дня!

...