<h1>Patrón Publicador/suscriptor o Publisher/subscriber</h1>
<button id="add">Agregar nuevo checkbox</button>
<input id="control" type="checkbox"/> Seleccionar
<h2>Nuevos checkboxes</h2>
<div id="container"></div>
input[type="checkbox"] {
width: 20px;
height: 20px;
}
const publisher = {
// Array que guardara los suscriptores interesados en alguna actividad del Publicador
subscribers: {
any: [] //Cualquier actividad del publicador
},
// agregar nuevo suscriptor para ser notificado de cambios en la actividad 'type'
subscribe (type, subscriberFn, context) {
if(!this.subscribers[type]) {
this.subscribers[type] = [];
}
this.subscribers[type].push({ fn: subscriberFn, context, type });
},
// Eliminar suscriptor de la actividad 'type' del Publicador
unsubscribe (type, subscribeFn, context) {
this.subscribers[type] = this.subscribers[type].filter(subscriber => {
if(subscriber.fn === subscribeFn && subscriber.context === context ) {
return false
}
return true;
});
},
// notificar a todos los observadores de un cambio, para esto recorre el arreglo
// de 'subscribers[type]' e invoca el método update de cada uno
publish (type, arg) {
this.subscribers[type].forEach( subscriber => {
subscriber.fn.call(subscriber.context, arg);
});
}
};
// Un observador con su método 'update'
const subscriber = {
update (context) {
console.log(context);
}
};
// Reusu de código copiando propieades, para extender objetos del DOM y puedan ser SUSCRIBER y/o PUBLISHER
function extend(child, parent) {
child = child || {};
for(const prop in parent) {
// evitar revisar la cadena de prototipos
if (parent.hasOwnProperty(prop)) {
child[prop] = parent[prop];
}
}
return child;
}
let addButton = document.querySelector('#add');
let control = document.querySelector('#control');
let container = document.querySelector('#container');
// El checkbox 'seleccionar' convertido en PUBLISHER
const publisherSeleccionar = extend(control, publisher);
publisherSeleccionar.addEventListener('click', function(e) {
this.publish('check', this.checked);
});
addButton.addEventListener('click', (e) => {
const check = document.createElement('input');
check.type = "checkbox";
// Cada checkbox creado sera convertido a SUBSCRIBER
const subscriberCheckbox = extend(check, subscriber);
subscriberCheckbox.update = function (value) {
this.checked = value;
};
subscriberCheckbox.addEventListener('click', () => {
publisherSeleccionar.unsubscribe('check', subscriberCheckbox.update, subscriberCheckbox);
});
publisherSeleccionar.subscribe('check', subscriberCheckbox.update, subscriberCheckbox);
container.append(subscriberCheckbox);
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.