Question: Is there a way to propagate a property change to a child element without triggering its render
function? Currently when I update the property in parent's switchViewModeHandler
it triggers a re-render on the child.
Use-case: toggling the parent into 'edit' mode should toggle the same for all of its children as well.
Doubt: Should I use custom events? Problem is that it will be a complex network of nested elements, with events it will become unwieldy to debug pretty quickly (already ran into this issue with Polymer).
Setup: Parent element:
class ParentElement extends LitElement {
@property() viewMode;
constructor() {
this.viewMode = ViewMode.editable;
}
static get properties() {
return {
viewMode: { type: String, reflect: true },
};
}
private switchViewModeHandler(event: MouseEvent): void {
this.viewMode =
(this.viewMode === ViewMode.editing) ? ViewMode.editable : ViewMode.editing; // update my own edit mode
const options: HTMLElement[] = (Array.from(this.children) as HTMLElement[]);
options.forEach((item: HTMLElement) => {
item.viewMode = this.viewMode;
});
}
render() {
return html`
<p>parent</p><label class="switch-wrapper">toggle edit mode
<input type="checkbox"
?checked="${this.viewMode === ViewMode.editing}"
@click="${
(event: MouseEvent): void => this.switchViewModeHandler(event)
}"
/>
</label>
<slot></slot><!-- child comes from here -->
`;
}
}
Child element:
class ChildElement extends LitElement {
@property() viewMode;
constructor() {
super();
this.viewMode = ViewMode.editable;
}
static get properties() {
return {
viewMode: { type: String, reflect: true },
};
}
render() {
console.log('child render() called');
return html`
<div class="viewer">child viewer</div>
<div class="editor mode-${this.viewMode}">child editor</div>
`;
}
}
Markup:
<parent-element>
<child-element data-type="special"></child-element
></parent-element>
Edit mode comes from a simple enum that's imported (omitted here):
export enum ViewMode {
readOnly = 'readOnly',
editable = 'editable',
editing = 'editing',
}
Here's a Codesandbox to play with: https://codesandbox.io/s/v1988qmn75
@
don't need to be bound or arrow functions. Method work fine and have slightly lower costs. - You don't need quotes around bindings, unless it's an interpolation. - You can declare property options in the decorator. - You can initialize a field in its declaration, you don't need a constructor. – Oloughlin