File: development/js/mixins/observable.js
import {Mixin} from '../utils/classes';
import Observable from '../utils/observer';
/**
* @module Mixins
*/
const OBSERVABLE = Symbol('__observableInstance');
/**
* The Observable utility as a mixin
* @class Mixins.Observable
*/
const ObservableMixin = Mixin({
/**
* Allows to test if a object is registered as a observer
*
* @method hasObserver
* @for Mixins.Observable
* @param {object} x The object to check against
* @param {function|string} [m = 'update'] The function or method name to check
* @return {boolean} True if registered, false if not
*
* @example
* import Observable from './mixins/observable';
*
* const logger = {
* log(message) {
* console.log(message);
* }
* }
*
* const MyClass = Observable(class {
* constructor() {
* this.addObserver(logger, 'log');
* }
* });
*
* let myInstance = new MyClass();
* myInstance.hasObserver(logger, 'log');
* // -> true
*/
hasObserver(o, m) {
if (this[OBSERVABLE]) {
return this[OBSERVABLE].hasObserver(o, m);
}
return false;
},
/**
* Adds a observer object to the observable
*
* @method addObserver
* @for Mixins.Observable
* @param {object} x The object to register as observer
* @param {function|string} [m = 'update'] Function or method to use as handler
* @return {this} The observable instance
*
* @example
* import Observable from './mixins/observable';
*
* const logger = {
* update(message) {
* console.log(message);
* }
* }
*
* const MyClass = Observable(class {
* constructor() {
* this.addObserver(logger);
* }
* });
*
* @example
* import Observable from './mixins/observable';
*
* const logger = {
* log(message) {
* console.log(message);
* }
* }
*
* const MyClass = Observable(class {
* constructor() {
* this.addObserver(logger, 'log');
* }
* });
*/
addObserver(o, m) {
if (!this[OBSERVABLE]) {
this[OBSERVABLE] = Observable();
}
this[OBSERVABLE].addObserver(o, m);
return this;
},
/**
* Removes an observer object from the observable
*
* @method removeObserver
* @for Mixins.Observable
* @param {object} x The object to remove
* @param {function|string} [m = 'update'] Function or method used as handler
* @return {this} The observable instance
*
* @example
* import Observable from './mixins/observable';
*
* const logger = {
* update(message) {
* console.log(message);
* }
* }
*
* const MyClass = Observable(class {
* constructor() {
* this.addObserver(logger);
* }
* });
*
* let myInstance = new MyClass();
* myInstance.removeObserver(logger);
*/
removeObserver(o, m) {
if (this[OBSERVABLE]) {
this[OBSERVABLE].removeObserver(o, m);
}
return this;
},
/**
* Notifies all registered observers with data
*
* @method notifyObservers
* @for Mixins.Observable
* @param {object} x The object to register as observer
* @param {function|string} [m = 'update'] Function or method to use as handler
* @return {this} The observable instance
*
* @example
* import Observable from './mixins/observable';
*
* const logger = {
* update(message) {
* console.log(message);
* }
* }
*
* const MyClass = Observable(class {
* constructor() {
* this.addObserver(logger);
* }
* });
*
* let myInstance = new MyClass();
* myInstance.notifyObservers('Sending a message');
* // logs "Sending a message"
*/
notifyObservers(...data) {
if (this[OBSERVABLE]) {
this[OBSERVABLE].notifyObservers(...data);
}
return this;
},
/**
* Destroys the observable, unregisters all observers
*
* @method destroyObservers
* @for Mixins.Observable
* @return {undefined} Nothing
*
* @example
* import Observable from './mixins/observable';
*
* const logger = {
* update(message) {
* console.log(message);
* }
* }
*
* const MyClass = Observable(class {
* constructor() {
* this.addObserver(logger);
* }
* });
*
* let myInstance = new MyClass();
* myInstance.notifyObservers('Sending a message');
* // logs "Sending a message"
*
* myInstance.destroyObservers();
*
* myInstance.notifyObservers('Sending another message');
* // nothing happens
*/
destroyObservers() {
if (this[OBSERVABLE]) {
this[OBSERVABLE].destroyObservers();
this[OBSERVABLE] = undefined;
}
}
});
export default ObservableMixin;