16일
Custom Element를 extends 한 경우 class 의 getter/setter 가 동작 하지 않을수 있다. 특히 다음과 같이 DOM 객체의 property를 할당하는 구문이 있을때 해당 현상이 나타난다.
class ServerControlPanel extends $.CustomElement {
constructor() {
super();
}
async render() {
console.log(this.serverStatus);
render(tmpl(this), this.shadowRoot);
$.get(this.shadowRoot, "server-status").status = this.serverStatus; // not call `server-status.status` setter.
}
}
이는 Custom Elements 의 경우 defined 되기전에 사용될수 있기 때문이다. 이를 Element의 Upgrade 라고 부른다. 이때 property가 먼저 할당이 되므로 prototype(js의 class 구현체)의 property 까지 접근을 하지 않고, instance 의 property 가 먼저 사용 되는 것이다. 따라서 해당 property를 먼저 delete 해주면 문제가 임시로 해결된다.
class ServerControlPanel extends $.CustomElement {
constructor() {
super();
}
async render() {
console.log(this.serverStatus);
render(tmpl(this), this.shadowRoot);
delete $.get(this.shadowRoot, "server-status").status; // delete property for prototype(temporary solution)
$.get(this.shadowRoot, "server-status").status = this.serverStatus;
}
}
물론 이는 완전한 해결책이 아니며 완전하게 해결하기 위해서는 다음과 같이 customElements.whenDefined
를 사용하여 custom element 가 정의 된 이후에 해당 property를 쓰도록 해야 한다.
class ServerControlPanel extends $.CustomElement {
constructor() {
super();
}
async render() {
console.log(this.serverStatus);
render(tmpl(this), this.shadowRoot);
await customElements.whenDefined("server-status"); // wait until element defined
$.get(this.shadowRoot, "server-status").status = this.serverStatus;
}
}
- ref
18일
- Landing Page explained
- 상위 1% 엔지니어의 7가지 간단한 습관