EventManager
Event-driven application are all around the web. Every (good) JS library or framework provides its method to listen and trigger custom events in order to keep in connection all the modules which it aims to handle.
In Proteins, this features is provided by 3 friendly methods that work with any object source:
on
: sets up a listener on an objecttrigger
: dispatches a custom eventoff
: destroys a listener
Import the methods
// from the Proteins module
import { on, trigger } from '@chialab/proteins';
Listen and trigger events
on(window, 'change', (timestamp) => {
console.log(timestamp);
});
trigger(window, 'change', Date.now());
Remove a specific listener
The simplest way to remove a listener from an object is to use the off
method:
const callback = (timestamp) => {
console.log(timestamp);
};
// set up the listener
on(window, 'change', callback);
// dispatch the event
trigger(window, 'change', Date.now());
// remove the listener
off(window, 'change', callback);
// dispatch the event again, but callback is not fired
trigger(window, 'change', Date.now());
Another way is to use the return value of the on
method:
// set up the listener
let listenerDestroyer = on(window, 'change', (timestamp) => {
console.log(timestamp);
});
// dispatch the event
trigger(window, 'change', Date.now());
// remove the listener
listenerDestroyer();
// dispatch the event again, but callback is not fired
trigger(window, 'change', Date.now());
Remove multiple (or all) listeners
You can quickly remove bunch of events too, using less parameters for the off
function:
// remove a single callback
off(window, 'change', callback);
// remove all listeners for the 'change' event
off(window, 'change');
// remove all listeners from window
off(window);
The EmitterMixin
and the Emitter
class
Proteins does not only provide the event feature, but extends it to classes, in order to add listeners directly to object instances. The built-in Factory.Emitter
class provides on
, off
and trigger
methods bound with its prototype:
import { Factory } from '@chialab/proteins';
class Shelf extends Emitter {
constructor() {
super();
this.books = [];
}
addBook(book) {
this.books.push(book);
this.trigger('added');
}
}
let shelf = new Shelf();
shelf.on('added', () => {
// render shelf
});
Listen to other objects
Proteins' Emitter
prototype has two special methods for listening to other Emitter
objects: listen
and unlisten
.
const library = new Emitter();
shelf.listen(library, 'bought', (book) => {
shelf.addBook(book);
});
library.trigger('bought', { title: 'The Chronicles of Narnia' });
// remove the listener
shelf.unlisten(library, 'bought');
As of the off
method, calling unlisten
without parameters destroys all listener generated by the scope.
Listen the invisible
If you already have a class (maybe from another library), but you want to add Proteins' events feature, you can use the mixin:
import { Factory, mix } from '@chialab/proteins';
const Chart = mix(MyChartClass).with(Factory.EmitterMixin);
let chart = new Chart();
chart.on('data', () => {
// render chart
});