I'm creating a little SPA framework, and I decided to integrate webcomponents. Everything works fine, but I'm just curious about 1 thing.
I extended HTML element and HTML element fragment with method add (note that it might not be perfect, it's still under the development)
DocumentFragment.prototype.add = function(options){
let element = document.createElement(options.elementType);
if (options.innerHTML){
element.innerHTML = options.innerHTML;
}
if (options.id){
element.id = options.id;
}
if (options.attributes){
for (let attr in options.attributes){
element.setAttribute(attr, options.attributes[attr]);
}
}
if (options.insertBefore){
this.insertBefore(element, options.insertBefore);
return element;
}
this.appendChild(element);
return element;
}
Element.prototype.add = DocumentFragment.prototype.add;
Now, in my view, I want to use this method like this:
root.add({
elementType: "test-component",
attributes: {
attr1: "value",
attr2: "26.1.2016",
attr3: "value"
}
It works, but the problem is, that createdCallback gets fired before I set attributes for this component, and I can't access these attribute in createdCallback.
Now, I'm using attributeChangedCallback to solve this, but it obviously isn't the best solution
attributeChangedCallback(attrName, oldVal, newVal) {
if (attrName == "attr1"){
*do something*
}
if (attrName == "attr2"){
*do something*
} ...
}
Is there a better way to solve this? Avoiding "add" method by extending innerHTML of parent element with something like
<test-component attr1="value"></test-component>
isn't very helpful, since this little "add" method simplifies my work a lot.
Every answer is much appretiated. Thanks
CreatedCallback gets fired whenever your element gets created(Obvious). Which is very useful when you are using custom elements 'declaratively', i.e. not appending it in DOM using js.
For your use case, CreatedCallback is getting fired as soon as you execute document.createElement
and since you are executing setAttribute
post that those won't be accessible in createdCallback
method.
Using attributeChangedCallback
is a valid alternative here. If you want to consider another one, you can use attachedCallback
which gets executed whenever you are appending your node to DOM i.e executing appendChild
on it.
Take a look at this article if you haven't already.