Reputation: 2368
Following this google tutorial on web components, and I like the way the author uses an anonymous class in the customElements.define
function call, as it avoids even more brackets when creating an immediately invoked function call.
I am using a static class variable to store the template element, so it's not queried every time the custom tag is instantiated.
The problem is in connectedCallback
I don't know how to refer to class name since it is an anonymous function. In python one could to type(self)
, but my research shows that typeof this
does not work in JS due to prototype magic.
window.customElements.define('my-uploader', class extends HTMLElement {
static template = document.getElementById("TEMPLATE_UPLOADER");
constructor() {
super(); // always call super() first
}
/** Custom Component Reactions **/
connectedCallback() {
let shadowRoot = this.attachShadow({mode: "open"});
shadowRoot.appendChild(document.importNode(ANONYMOUS_NAME.template, true)); // <--- How to refer to the class name here?
}
How to refer to the class' ANONYMOUS_NAME
in connectedCallback
?
Upvotes: 3
Views: 1214
Reputation: 21173
When working with shadowDOM you (in general) create everything in the constructor
The connectedCallback
triggers for every DOM insertion OR DOM CHANGE!
Think Drag/Drop interactions, or sorting DOM Elements.
It will error if you try to attach a shadowRoot again
You can chain all JS, see below
importNode
is for multiple Documents; you will see cloneNode
in the better blogs.
append
has more power, see the docs.
It just wasn't available in IE, so old JS-Geezers don't know about it.
customElements.define('my-uploader', class extends HTMLElement {
constructor() {
let template = document.getElementById("TEMPLATE_UPLOADER").content;
// don't believe the (MDN) documentation, you CAN execute JS BEFORE super()
// you just can't access 'this' BEFORE super()
super() // super sets AND returns the 'this' scope
.attachShadow({mode: "open"}) // sets AND returns this.shadowRoot;
.append(template.cloneNode(true));
}
});
<template id="TEMPLATE_UPLOADER">
<style>
:host{
color:red;
}
</style>
<h1>I am <slot></slot></h1>
</template>
<h1>Hello Web Components!</h1>
<my-uploader>Uploader!</my-uploader>
Note! The constructor
also runs on document.createElement("my-uploader")
when your Element DOES NOT EXIST in DOM yet! Only when added to the DOM the connectedCallback
runs
Upvotes: 1
Reputation: 1327
You can either name your class, it's the cleanest way, or you can use this.constructor
to get your static variable value :
window.customElements.define('my-uploader', class extends HTMLElement {
static template = document.getElementById("TEMPLATE_UPLOADER");
constructor() {
super(); // always call super() first
}
/** Custom Component Reactions **/
connectedCallback() {
let shadowRoot = this.attachShadow({mode: "open"});
shadowRoot.appendChild(document.importNode(this.constructor.template, true));
}
Upvotes: 7