Как может быть вызвана сделка «connectedCallback, когда ваш элемент больше не подключен», кодирующий веб-компонент - PullRequest
3 голосов
/ 02 июля 2019

Это заявление, вставленное в мой вопрос, было скопировано с https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#Using_the_lifecycle_callbacks.

Как разработчик, не имеющий опыта работы с Webcomponent, я пытаюсь понять все рекомендуемые правила и лучшие практики, рекомендованные до сих пор.

Продолжая читать, он говорит "... используйте Node.isConnected, чтобы убедиться".Совершенно очевидно, что это означает: проверьте, все ли еще подключено, но неясно, по крайней мере для меня, что мне следует сделать, чтобы обойти это или что я должен ожидать в некоторых случаях.

Мой случайЯ создаю веб-компонент для прослушивания SSE (Server Sent Events).Это будет полезно для инструментальной панели alife и нескольких других сценариев.На событие SSE в основном будут реагировать либо NodeJs, либо Spring Webflux после получения из Kafka Stream.

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

Кроме того, я не читал никаких рекомендаций в Best Practices относительно "элемент больше не подключен".

Я прочитал несколько прекрасных обсуждений:

Может ли пользовательский элемент подключен к обратному вызову, который будет называться больше, чем один раз перед диском

откуда я узнал, что я всегда могу доверять этому конструктору жизненного цикла -> connectedCallback -> disconnectedCallback.

И

Как получить 'connectedCallback' для когдавсе дочерние пользовательские элементы были подключены

, где в основном я узнал, что не существует специального метода, «вызываемого после обновления всех детей»

Оба вопроса проходят близко к моему вопросу, но это нене отвечайте мне: о какой проблеме или риске следует знать или как обойти возможность вызова «connectedCallback», когда ваш элемент больше не подключен »?В моем сценарии, описанном выше, есть какое-то лечение, которое я пропускаю?Должен ли я создать некоторый наблюдатель, который срабатывает, когда элемент больше не доступен, чтобы воссоздать объект источника событий и снова добавить прослушиватель к такому объекту источника событий?

Я вставил приведенный ниже код для иллюстрации, и полный пример Webcomponent можно клонироватьот https://github.com/jimisdrpc/simplest-webcomponet и его бэкэнда от https://github.com/jimisdrpc/simplest-kafkaconsumer.

const template = document.createElement('template');
template.innerHTML = `<input id="inputKafka"/> `;

class InputKafka extends HTMLElement {
  constructor() {
    super();
  }

  connectedCallback() {

    this.attachShadow({mode: 'open'})
    this.shadowRoot.appendChild(template.content.cloneNode(true))

    const inputKafka = this.shadowRoot.getElementById('inputKafka');

    var source = new EventSource('http://localhost:5000/kafka_sse');

    source.addEventListener('sendMsgFromKafka', function(e) {
      console.log('fromKafka');
      inputKafka.value = e.data;
    }, false);

  }
  attributeChangedCallback(name, oldVal, newVal) {
    console.log('attributeChangedCallback');
  }

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

  adoptedCallback() {
    console.log('adoptedCallback');
  }
}

window.customElements.define("input-kafka", InputKafka);

Ответы [ 2 ]

2 голосов
/ 05 июля 2019

В дополнение к тому, что сказал @supersharp, я добавлю еще одну вещь:

Делать не вызов attachShadow в connectedCallback:

Ваш код:

class InputKafka extends HTMLElement {
  connectedCallback() {
    this.attachShadow({mode: 'open'})
    this.shadowRoot.appendChild(template.content.cloneNode(true))
    const inputKafka = this.shadowRoot.getElementById('inputKafka');

    const source = new EventSource('http://localhost:5000/kafka_sse');
    source.addEventListener('sendMsgFromKafka', function(e) {
      console.log('fromKafka');
      inputKafka.value = e.data;
    }, false);
  }
}

Ваш код должен вызвать attachShadow в конструкторе

class InputKafka extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({mode: 'open'})
    this.shadowRoot.appendChild(template.content.cloneNode(true))
    const inputKafka = this.shadowRoot.getElementById('inputKafka');

    const source = new EventSource('http://localhost:5000/kafka_sse');
    source.addEventListener('sendMsgFromKafka', function(e) {
      console.log('fromKafka');
      inputKafka.value = e.data;
    }, false);
  }
}

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

Если вы не используете shadowDOM, вам следует подождатьдо тех пор, пока не будет вызван connectedCallback, чтобы добавить ваши дочерние элементы, как указано в Требованиях для пользовательских конструкторов элементов .

Я либо создаю свои дочерние элементы один раз, если они сложные, или каждый разкомпонент подключен, когда свойство изменяется или когда атрибут изменяется.

2 голосов
/ 03 июля 2019

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

В описанном вами случае использования, если вы используете постоянное одностраничное приложение для размещения вашего веб-компонента, этого никогда не произойдет. На самом деле ваш пользовательский элемент никогда не будет отключен, пока страница не будет закрыта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...