[Tips] this.text is not for this element in a base class of an extended element
Root Cause
In an extended element, this.text refers to the text property for the extended element, not for the base element. This is as designed.
How to get the proper text object of the base element in directives
class MyBaseElement extends i18n(HTMLElement) {
constructor() { super(); this.items = ['item 1', 'item 2', 'item 3']; ... }
render() {
let binding = bind(this, 'my-base-element');
let text = this.getText('my-base-element', import.meta);
// text has not been initialized at the first rendering before preprocessing
text = text.model ? text : null;
return html`${'my-base-element', binding}
${text
? repeat(this.items, i => i, i => html`<div>${text.header} ${i}</div>`)
: nothing /* empty (or any value) at the first rendering */ }
<template>
<span id="header">Header</span>
</template>`;
}
}
Define an inner template to avoid the this identity issue
const innerBinding = bind('inner-template', import.meta);
class MyBaseElement extends i18n(HTMLElement) {
constructor() { super(); this.items = ['item 1', 'item 2', 'item 3'];
this.addEventListener('lang-updated', this.langUpdated);
// 'lang-updated' event may come asynchronously after that for 'my-base-element'
innerBinding.element.addEventListener('lang-updated', this.langUpdated.bind(this));
...
}
connectedCallback() { this.invalidate(); }
langUpdated(event) { this.invalidate(); }
render() {
return html`${bind(this, 'my-base-element')}
${repeat(this.items, i => i, i =>
html`${'inner-template', innerBinding}<div>Header ${i}</div>`)}`;
}
invalidate() { /* render */ ... }
}
[Tips]
this.text
is not forthis
element in a base class of an extended elementRoot Cause
In an extended element,
this.text
refers to the text property for the extended element, not for the base element. This is as designed.How to get the proper
text
object of the base element in directivesDefine an inner template to avoid the
this
identity issue