The Observable module

Ojay.Observable is an extension of the JS.Observable module that adds an on() method that behaves similarly to DomCollection#on(), used for monitoring DOM events. It can be used to set up an interface through which an object may publish named events, and other objects can listen to such events. In other words, it provides an event system for non-DOM JavaScript objects.

Examples

Using Observable in your own classes

Here’s an example of a class that uses the module:

    var Player = new JS.Class({
        include: Ojay.Observable,

        play: function() {
            this.startTime = this.getTime();
            this.notifyObservers('start');
        },

        pause: function() {
            var elapsed = this.getTime() - this.startTime;
            this.notifyObservers('pause', elapsed);
        },

        getTime: function() {
            return Number(new Date()) / 1000;
        }
    });

The getTime() method simply returns the current timestamp in seconds. The play() method records the current time and fires the start event by using notifyObservers() to send a message to its observers. The pause() method simply publishes a pause event that sends the elapsed time to any listeners.

Some client code to listen to one of these objects might look like this:

    var p = new Player();

    p.on('start', function(player) {
        alert(player.startTime);
    });

    p.on('pause', function(player, timeElapsed) {
        alert(timeElapsed);
    });

All listeners receive the object that fired the event as their first argument, and any data published by said object with the event as the subsequent arguments. An optional third argument to on() specifies the execution context of the listener function, so for example:

    p.on('start', function() {
        // this === someObject
    }, someObject);

All calls to on() return a MethodChain object that, by default, will fire on the object publishing the event, so the following:

    p.on('start').pause();

Will cause p to call its pause() method whenever its start event is fired.

Class-level listeners

When you include Ojay.Observable into a class, the on() method gets added to the class itself, allowing you to listen to all instances of the class with a single call. The callback is sent a reference to the instance that fired the event:

    Player.on('pause', function(p) {
        // p is an instance of class Player
    });

In general, calling notifyObservers() on an object will also find the object’s class, the class’ ancestor classes and included modules, and call notifyObservers() on all the classes/modules that provide that method. You can use this to modify the behaviour of all objects of a particular type; see the example for more ideas.

For further information on this module, see the JS.Observable documentation.