packages/lit-dev-content/site/tutorials/content/wc-to-lit/10.md
Now that you have gotten rid of the <template> element in index.html, refactor the code to take advantage of Lit template features in the newly-defined render() method. You can start by leveraging Lit's event listener binding syntax:
<button
class="thumb_down"
@click=${() => {this.vote = 'down'}}>
...
<button
class="thumb_up"
@click=${() => {this.vote = 'up'}}>
Lit templates can add an event listener to a node with the @EVENT_NAME binding syntax where, in this case, you update the vote property every time these buttons are clicked.
{% aside "info" %}
You can learn more about the Lit binding syntax in the Lit Expressions documentation.
{% endaside %}
Next:
_boundOn[Up|Down]Click class members.connectedCallback.disconnectedCallback._on[Up|Down]Click methods.{% switchable-sample %}
export class RatingElement extends HTMLElement {
private _rating = 0;
private _vote: 'up'|'down'|null = null;
connectedCallback() {
this.attachShadow({mode: 'open'});
this.render();
}
// remove disonnectedCallback and _onUpClick and _onDownClick
...
}
export class RatingElement extends HTMLElement {
_rating = 0;
_vote = null;
connectedCallback() {
this.attachShadow({mode: 'open'});
this.render();
}
// remove disonnectedCallback and _onUpClick and _onDownClick
...
}
{% endswitchable-sample %}
You were able to remove:
disconnectedCallback entirely.connectedCallback making it look much more elegant._onUpClick and _onDownClick listener methods.Finally, update the property setters to utilize the render method so that the DOM can update when either the properties or attributes change:
{% switchable-sample %}
set rating(value) {
this._rating = value;
// remove the logic for imperatively setting the innerText
// since it's handled in render()
this.render();
}
...
set vote(newValue) {
...
this._vote = newValue;
this.setAttribute('vote', newValue!);
// call this.render() at the end of the setter
this.render();
}
set rating(value) {
this._rating = value;
// remove the logic for imperatively setting the innerText
// since it's handled in render()
this.render();
}
...
set vote(newValue) {
...
this._vote = newValue;
this.setAttribute('vote', newValue);
// call this.render() at the end of the setter
this.render();
}
{% endswitchable-sample %}
{% aside "warn" %}
This is not the most efficient way to update the DOM.
Synchronously calling render() in the setters of rating and vote is not the most efficient way to update the DOM, but it is a good way to illustrate where LitElement calls render() (next step).
{% endaside %}
Here, you:
rating setter.render from the vote setter.Now the template is much more readable as you now can see where the bindings and event listeners are applied.
You should have a functioning <rating-button> that should look like this when the upvote is pressed!