I am trying to use the keyed directive in lit element. I don't want to do the ?action=${action}
because just adding the action
attribute or removing the action
attribute is cleaner for true or false. However, the keyed directive does seem to reset the element when I add or remove the action
attribute. Any ideas, please, on how to make this work without the hacky ?action=${action}
?
${keyed(this.active, html`
<add-transaction
@add-catergory=${() => this.openAddCatergory()}
@save-trans=${this.#saveTrans}
.label=${this.label}
id="add-transaction"></add-transaction>`)}
_loadNewTransactionPage() {
const el = this.renderRoot.querySelector('#add-transaction');
el.setAttribute('active', '');
}
keyed()
has nothing to do with, and knows nothing about, attributes. The key is any JS value (not necessarily even a property of an element) and if it changes the template instance is cleared and re-rendered.
If you do want to key off an attribute, you need to pass an attribute value to keyed()
and you need to re-render when that attribute changes. Lit's reactive properties will do just that. So make a reactive property out of action
(presumably it's "action", but you also use "active" in your code).
class MyElement extends LitElement {
@property() action;
render() {
return html`
${keyed(this.action, html`
<add-transaction
@add-catergory=${() => this.openAddCatergory()}
@save-trans=${this.#saveTrans}
.label=${this.label}
id="add-transaction"></add-transaction>`)}
`;
}
}
Now when action
changes on a MyElement, the template will re-render and the new value of this.action
will be used as the key.
This in only combining reactive properties with keyed()
. Again, keyed()
can be used with any value from anywhere.