section ActiveEvent section

Description

Create observable events, and attach event handlers to any class or object. Supports class events that cascade to all instances.

Setup

Before you can use ActiveEvent you call ActiveEvent.extend. If you extend a class, both the class itself will become observable, as well as all of it's instances.

ActiveEvent.extend(MyClass); //class and all instances are observable
ActiveEvent.extend(my_object); //this object becomes observable

Creating Events

You can create an event inside any method of your class or object by calling the notify method with name of the event followed by any arguments to be passed to observers.

var Message = function(){};
ActiveEvent.extend(Message);
Message.prototype.send = function(text){
    //message sending code here...
    this.notify('sent',text);
};

Observing Events

To observe an event call the observe method with the name of the event you want to observe, and the observer function. The observer function will receive any additional arguments passed to notify. If observing a class, the instance that triggered the event will always be the first argument passed to the observer. observeOnce works just like observe in every way, but is only called once.

Message.observe('sent',function(message,text){
    //responds to all sent messages
});
 var m = new Message();
m.observe('sent',function(text){
    //this will only be called when "m" is sent
});
 observable_hash.observe('set',function(key,value){
    console.log('observable_hash.set: ' + key + '=' + value);
});
 observable_hash.observeOnce('set',function(key,value){
    //this will only be called once
});

Function Binding

You can bind and curry your observers by adding extra arguments, which will be passed to ActiveSupport.Function.bind:

Message.observe('sent',function(message,text){
    //this == context
},context);
 Message.observe('sent',function(curried_argument,message,text){
    //this == context
},context,curried_argument);

Control Flow

When notify is called, if any of the registered observers for that event return false, no other observers will be called and notify will return false. Returning null or not calling return will not stop the event.

Otherwise notify will return an array of the collected return values from any registered observer functions. Observers can be unregistered with the stopObserving method. If no observer is passed, all observers of that object or class with the given event name will be unregistered. If no event name and no observer is passed, all observers of that object or class will be unregistered.

Message.prototype.send = function(text){
    if(this.notify('send',text) === false)
        return false;
    //message sending code here...
    this.notify('sent',text);
    return true;
};
 var m = new Message();
 var observer = m.observe('send',function(message,text){
    if(text === 'test')
        return false;
});
 m.send('my message'); //returned true
m.send('test'); //returned false
 m.stopObserving('send',observer);
 m.send('test'); //returned true

Object.options

If an object has an options property that contains a callable function with the same name as an event triggered with notify, it will be treated just like an instance observer.

var Widget = function(options){
    this.options = options;
};
ActiveEvent.extend(Widget);
 var my_widget = new Widget({
    afterChange: function(){}
});
//equivelent to:
var my_widget = new Widget();
my_widget.observe('afterChange',function(){});

Utilities