Определение обратных вызовов жизненного цикла пользовательского элемента внутри конструктора - PullRequest
2 голосов
/ 12 января 2020

Следующее определяет, создает и, наконец, вставляет экземпляр моего «автономного пользовательского элемента» в контейнер:

class MyCustomElement extends HTMLElement {
  static get elementName() {
    return 'my-custom-element';
  }

  constructor() {
    const self = super();
    let _myPrivateData = 'privateValue';

    // the following does not cause the callback to be invoked at all!
    MyCustomElement.prototype.connectedCallback = function() {
      console.log('connected!');
    };

    return self;
  }

  //// this would've got invoked anyways, but there's no access to the `_myPrivateData`
  // connectedCallback() {
  //     console.log('connected!');
  // }
}

let myCustomElementName = MyCustomElement.elementName;
customElements.define(myCustomElementName, MyCustomElement);

let myCustomElement = document.createElement(myCustomElementName);
let container = document.getElementById('container');
container.appendChild(myCustomElement);
<div id="container"></div>

Я определил connectedCallback внутри "конструктора", чтобы иметь доступ к _myPrivateData, но затем к обратному вызову не вызывается вообще! Наличие идентичного фрагмента кода сразу после «тела класса» действительно вызывает обратный вызов за счет отсутствия доступа к _myPrivateData.

Почему это так? Как мне подойти к проблеме, чтобы иметь доступ к _myPrivateData (сохраняя ее "приватную" природу) и иметь работающий вызов обратного вызова?

1 Ответ

2 голосов
/ 13 января 2020

Из-за реализации пользовательского элемента вы должны определить все обратные вызовы, прежде чем элемент будет определен с помощью customElements.define(). Эти обратные вызовы доступны только для чтения.

Чтобы справиться с личными значениями, вы можете определить свой собственный обратный вызов, который будет вызываться стандартным методом connectedCallback().

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

class MyCustomElement extends HTMLElement {
  constructor() {
    super()
    let _myPrivateData = 'privateValue'

    // the following does not cause the callback to be invoked at all!
    this.connectedCallback = function() {
      console.log('connected! : ' + _myPrivateData )
    }
  }

  connectedCallback() {
      this.connectedCallback()
  }
}

customElements.define('my-custom-element', MyCustomElement)
<my-custom-element></my-custom-element>

Обновление

Эффективные обратные вызовы жизненного цикла фактически только для чтения / заморожены . Вы не можете изменить их после определения пользовательского элемента.

Учтите, что при вызове customElements.define() обратные вызовы жизненных циклов копируются в реестр пользовательских элементов из записей обратного вызова class с тем же именем или устанавливаются на void(), если имя обратного вызова не не существует

Когда создается экземпляр пользовательского элемента, это вызываемые копии обратного вызова, а не методы класса обратного вызова prototype. Вы не можете получить доступ и, следовательно, изменить эти копии.

Вы все еще можете модифицировать обратные вызовы класса (записи prototype), но это не повлияет на жизненный цикл пользовательского элемента.

Завещание обеспечит постоянство жизненного цикла для всех одинаковых экземпляров пользовательских элементов.

...