Observable
Credits: This module is a reimplementation of Riot Observable made to support typings, OOP, nested observers, and debugging utility.
The idea behind this refactor is to add a global event emitter to your application and be able to create child-observers that can have their own namespaced events. You can also wrap an existing object and make it observable; it will have the exact same API.
#
Exampleimport { Observable } from '@riot-tools/sak';
const observer = new Observable();
// or
const somethingToMakeAnObserver = {};const observer = new Observable(somethingToMakeAnObserver);
// with configurable optionsconst observer = new Observable(null, {
// Can spy on the observer for debugging spy: ({ fn, event, listener, context, args }) => {
if (fn === 'trigger') {
console.log(event, args, context); } }});
observer.on(ev, fn);observer.one(ev, fn);observer.off(ev, fn);observer.trigger(ev, fn);
#
Child observersOnce an observer is instantiated, you can observe other components. This gives your component a limited observable API that ties into its parent observer.
const modal = {};
// those events can have namespaced prefixesobserver.observe(modal, 'modal');
observer.on('modal-open', () => {});
// Because modal is namespaced, it will automatically prefix the event name with `modal`modal.trigger('open');
// destroy when done;modal.cleanup();
#
Riot pluginYou can install your observer onto your components as a plugin via riot.install
. Any listeners that are attached via this.on
or this.one
are automatically cleaned up before a comonent unmounts.
Riot.install(component => observer.install(component));
component.riot
<something>
...
<script>
export default {
onClick() {
this.trigger('something-clicked'); },
onMounted() {
// will be automatically cleaned up before unmount this.on('user-fetched', (user) => this.update({ user }));
fetchUser(); } } </script></something>
You can also directly install the observer API on a specific component using the same function
<script>
import { observer } from './events';
export default observer.install({
onBeforeMount: () => {} });</script>