6

我的问题中粘贴的该声明是从https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#Using_the_lifecycle_callbacks复制的。

作为一个没有 Webcomponent 经验的开发人员,我试图了解迄今为止推荐的所有经验法则和最佳实践。

继续阅读它说“......使用 Node.isConnected 来确保”。这意味着什么很明显:检查它是否仍然连接但不清楚,至少对我来说,我应该做些什么来解决它或者在某些情况下我应该期待什么。

我的情况是我正在创建一个 Web 组件来监听 SSE(服务器发送事件)。这对于生活仪表板和其他几个场景很有用。从 Kafka Stream 消费后,SSE 事件将基本上由 NodeJs 或 Spring Webflux 响应。

到目前为止,我所做的所有简单示例都没有遇到在连接回调期间元素不再连接的任何问题。

此外,我没有阅读最佳实践中关于“不再连接的元素”的任何建议。

我读了一些很好的讨论:

can-a-custom-elements-connectedcallback-be-called-more-than-once-before-disc

从那里我了解到我总是可以信任这个生命周期构造函数--> 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);
4

2 回答 2

4

在自定义元素断开连接后调用的唯一情况connectedCallback()是在您使用它时:在创建它后快速移动或移除它有时可能会导致这种情况。

在您描述的用例中,如果您使用持久的单页应用程序来托管您的 Web 组件,这将永远不会发生。实际上,在页面关闭之前,您的自定义元素永远不会断开连接。

于 2019-07-03T16:34:05.713 回答
2

除了@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被调用以添加您的子元素,如自定义元素构造函数的要求中指定的那样。

如果我的子元素很复杂,或者每次连接组件、属性更改或属性更改时,我要么创建一次子元素。

于 2019-07-05T19:59:03.100 回答