Creating a Web Component with Data-Binding Capability
by valkoivo
HTML
<!DOCTYPE html>
<html>
<body>
<my-provider id="provider_id"></my-provider>
<my-consumer id="consumer_id" provider_id="provider_id" provider_event="my-provider-data-changed"></my-consumer>
</body>
<script>
</script>
</html>
JavaScript
class MyProvider extends HTMLElement {
constructor(){
super();
this._data = {
value: 'Some initial value'
};
}
_createEvent(){
this._event = new CustomEvent('my-provider-data-changed');
}
_announceDataReady(){
this.dispatchEvent(this._event);
}
_announceDataChanged(){
this.dispatchEvent(this._event);
}
connectedCallback() {
this._createEvent();
this._announceDataReady();
}
changeData(new_value){
this._data.value = new_value;
this._announceDataChanged();
}
}
const CustomInterfaceExposable = Sup => class extends Sup {
retrieveDataObject(){
return this._data;
}
}
class MyCustomProvider extends CustomInterfaceExposable(MyProvider) {
}
const ProviderConnectable = Sup => class extends Sup {
constructor(){
super();
this.provider_id = this.getAttribute("provider_id");
this.provider_event = this.getAttribute("provider_event");
}
connectedCallback() {
this._provider = this._identifyProvider();
this._onProviderIdentified();
this._subscribeToProviderEvent();
}
disconnectedCallback() {
this._unsubscribeFromProviderEvent();
}
_identifyProvider(provider_id){
return document.getElementById(
this.provider_id
);
}
_onProviderIdentified(){
// Do something to initialize
}
_subscribeToProviderEvent(){
this._onProviderDataChangedBinded = this._onProviderDataChanged.bind(this);
this._provider.addEventListener(
this.provider_event,
this._onProviderDataChangedBinded
);
}
_isProviderReady(){
return this._provider && (typeof(this._provider.connectedCallback) === 'function');
}
_onProviderDataChanged(event){
// Do something with changed data
}
_unsubscribeFromProviderEvent(){
this._provider.removeEventListener(
this.provider_event,
this._onProviderDataChangedBinded
);
}
}
const CustomInterfaceConsumable = Sup => class extends Sup {
_retrieveProviderDataObject(provider){
return provider.retrieveDataObject();
}
}
class MyConsumer extends...