Skip to content
millermedeiros edited this page Aug 31, 2012 · 21 revisions

Few examples on how to use Signals for custom event dispatching. Check the documentation for a a full reference of available methods and properties.

Notes about node.js, AMD and browser

On node.js and AMD the signals namespace is optional since v0.8.0:

node.js

var Signal = require('signals');
var mySignal = new Signal();

AMD

define(['signals'], function(Signal){
  var mySignal = new Signal();
});

Browser globals

On the browser you should access the Signal constructor through the signals namespace. A common practice is to create an alias for brevity:

var Signal = signals.Signal;
var mySignal = new Signal();

Setup code (required for all examples)

  //store local reference for brevity
  var Signal = signals.Signal;
  
  //custom object that dispatch signals
  var myObject = {
    started : new Signal(), //past tense is the recommended signal naming convention
    stopped : new Signal()
  };

Basic

Single Listener

  function onStarted(param1, param2){
    alert(param1 + param2);
  }
  myObject.started.add(onStarted); //add listener
  myObject.started.dispatch('foo', 'bar'); //dispatch signal passing custom parameters
  myObject.started.remove(onStarted); //remove a single listener

Multiple Listeners

  function onStopped(){
    alert('stopped');
  }
  function onStopped2(){
    alert('stopped listener 2');
  }
  myObject.stopped.add(onStopped);
  myObject.stopped.add(onStopped2);
  myObject.stopped.dispatch();
  myObject.stopped.removeAll(); //remove all listeners of the `stopped` signal

Multiple Dispatches

  var i = 0;
  myObject.started.add(function(){
    i += 1;
    alert(i);
  });
  myObject.started.dispatch(); //will alert 1
  myObject.started.dispatch(); //will alert 2

Multiple Dispatches + addOnce()

  var i = 0;
  myObject.started.addOnce(function(){
    i += 1;
    alert(i);
  });
  myObject.started.dispatch(); //will alert 1
  myObject.started.dispatch(); //nothing happens

Enable/Disable Signal

  var i = 0;
  myObject.started.add(function(){
    i += 1;
    alert(i);
  });
  myObject.started.dispatch(); //will alert 1
  myObject.started.active = false;
  myObject.started.dispatch(); //nothing happens
  myObject.started.active = true;
  myObject.started.dispatch(); //will alert 2

Stop/Halt Propagation (method 1)

  myObject.started.add(function(){
    myObject.started.halt(); //prevent next listeners on the queue from being executed
  });
  myObject.started.add(function(){
    alert('second listener'); //won't be called since first listener stops propagation
  });
  myObject.started.dispatch();

Stop/Halt Propagation (method 2)

  myObject.started.add(function(){
    return false; //if handler returns `false` will also stop propagation
  });
  myObject.started.add(function(){
    alert('second listener'); //won't be called since first listener stops propagation
  });
  myObject.started.dispatch();

Set execution context of the listener handler

  var foo = 'bar';
  var obj = {
    foo : 10
  };
  
  function handler1(){
    alert(this.foo);
  }
  function handler2(){
    alert(this.foo);
  }
  //note that you cannot add the same handler twice to the same signal without removing it first
  myObject.started.add(handler1); //default execution context
  myObject.started.add(handler2, obj); //set a different execution context
  myObject.started.dispatch(); //first handler will alert "bar", second will alert "10".

Advanced

Set listener priority/order (v0.5.3+)

  var handler1 = function(){
    alert('foo');
  };
  var handler2 = function(){
    alert('bar');
  };
  myObject.started.add(handler1); //default priority is 0
  myObject.started.add(handler2, null, 2); //setting priority to 2 will make `handler2` execute before `handler1`
  myObject.started.dispatch(); //will alert "bar" than "foo"

Enable/Disable a single SignalBinding

  var handler1 = function(){
    alert('foo bar');
  };
  var handler2 = function(){
    alert('lorem ipsum');
  };
  var binding1 = myObject.started.add(handler1); //methods `add()` and `addOnce()` returns a SignalBinding object
  myObject.started.add(handler2);
  myObject.started.dispatch(); //will alert "foo bar" than "lorem ipsum"
  binding1.active = false; //disable a single binding
  myObject.started.dispatch(); //will alert "lorem ipsum"
  binding1.active = true;
  myObject.started.dispatch(); //will alert "foo bar" than "lorem ipsum"

Manually execute a signal handler

  var handler = function(){
    alert('foo bar');
  };
  var binding = myObject.started.add(handler); //methods `add()` and `addOnce()` returns a SignalBinding object
  binding.execute(); //will alert "foo bar"

Retrieve anonymous listener

  var binding = myObject.started.add(function(){
    alert('foo bar');
  });
  var handler = binding.getListener(); //reference to the anonymous function

Remove / Detach anonymous listener

  var binding = myObject.started.add(function(){
    alert('foo bar');
  });
  myObject.started.dispatch(); //will alert "foo bar"
  binding.detach();
  alert(binding.isBound()); //will alert `false`
  myObject.started.dispatch(); //nothing happens

Check if binding will execute only once

  var binding1 = myObject.started.add(function(){
    alert('foo bar');
  });
  var binding2 = myObject.started.addOnce(function(){
    alert('foo bar');
  });
  alert(binding1.isOnce()); //alert "false"
  alert(binding2.isOnce()); //alert "true"

Change listener execution context on-the-fly

  var foo = 'bar';
  var obj = {
    foo : "it's over 9000!"
  };
  var binding = myObject.started.add(function(){
    alert(this.foo);
  });
  myObject.started.dispatch(); //will alert "bar"
  binding.context = obj;
  myObject.started.dispatch(); //will alert "it's over 9000!"

Add default parameters to Signal dispatch (v0.6.3+)

  var binding = myObject.started.add(function(a, b, c){
    alert(a +' '+ b +' '+ c);
  });
  binding.params = ['lorem', 'ipsum']; //set default parameters of the binding
  myObject.started.dispatch('dolor'); //will alert "lorem ipsum dolor"

Check if Signal has specific listener (v0.7.0+)

function onStart(a){
  console.log(a);
}
myObject.started.add(onStart);
myObject.started.has(onStart); // true

Memorize previously dispatched values / forget values (v0.7.0+)

myObject.started.memorize = true; // default is false
myObject.started.dispatch('foo');

// add()/addOnce() will automatically fire listener if signal was dispatched before
// will log "foo" since it keeps record of previously dispatched values
myObject.started.addOnce(console.log, console);

// dispatching a new value will overwrite the "memory"
myObject.started.dispatch('lorem');
// will log "lorem"
myObject.started.addOnce(console.log, console);

myObject.started.forget(); // forget previously dispatched values (reset signal state)
myObject.started.addOnce(console.log, console); // won't log till next dispatch (since it "forgot")
myObject.started.dispatch('bar'); // log "bar"

Listening for multiple signals at once

Check the CompoundSignal repository.

Dispatching arbitrary events

In some cases it might be useful to listen/dispatch to arbitrary event types, see SignalEmitter for more info.

More

For more examples check the unit tests located inside the dev/tests folder.

Check the documentation for a a full reference of available methods and properties.

Back to Home