onattributechanged is not called immediately OR on attach
wasimpathan5 opened this issue · 1 comments
Please refer below code snippet,
<script>
var myComponent = {
init: function (event) {
this.el = event.currentTarget;
this.render();
},
render: function () {
this.el.innerHTML = '<p>My wicked element!</p>';
},
onattributechanged: function (e) {
console.log('attribute changed', e.newValue);
}
}
wickedElements.define('.myClass', myComponent);
var el = document.createElement('div');
el.classList.add('myClass');
document.body.appendChild(el);
el.setAttribute('attr1', 'val1'); // Doesn't trigger attribute change
setTimeout(function () {
el.setAttribute('attr2', 'val2'); // Triggers attribute change
}, 0);
</script>
<div class="myClass" attr3="val3"></div> <!-- Doesn't trigger attribute change -->
Uhm ... beside this being a regular-elements bug, and not a wicked elements one, I'm not sure I want to change anything there.
In both libraries, you have a connected
event, but with wicked elements you also have an init
callback, which is your entry point to do anything attributes related.
Being based on MutationObserver, nodes are always setup asynchronously, which is why you don't see the first attribute change notification when you el.setAttribute('attr1', 'val1');
right after creating the node or putting the node into the DOM.
Accordingly, since the init
method would give you access to any attribute you need, and it's there to grant nothing happens before the init
is called, all you should care about are changes after the init
happens.
Same would be with onconnected
, at that time any change you need due attributes values can be easily retrieved.
This avoids:
- complexity of delaying all events after the
init
happens, since that's theinit
contract - multiple events triggered per each attribute even if there was no action needed
- trust any synchronous behavior since the whole point here is to never block
I understand that Custom Elements would behave differently here, invoking the callback per each observed attribute, but I also would like to underline here the list of observed attributes is arbitrary and, on top of that, if an attribute never changed, invoking an onattributechanged
makes literally no sense to me, so that your last expectation about the <div class="myClass" attr3="val3"></div>
is IMO not correct, 'cause the DIV was created as such, and no attribute ever changed since its creation.
You could stretch this concept so that it covers also manual synchronous mutation of attributes before the node is initialized/upgraded as wickedElement, and see that you actually don't need that attribute change to happen, you just need to setup, whatever you need to setup, once through the init
callback.