Publish/subscribe

Like many libraries, Ractive implements the publish/subscribe mechanism to allow you to respond to, or trigger, particular events.

Subscribe

To subscribe to an event, use ractive.on():

ractive = new Ractive({
  el: 'body',
  template: '<button on-click="activate">click me!</button>'
});
ractive.on( 'activate', function () {
  alert( 'Activating!' );
});

This can be used to subscribe to any of the following type of events:

Multiple events to one handler

You can subscribe a handler to more than one event by separating event names with a space:

ractive.on( 'activate select', function () {...} );

This example will fire for either an activate event or a select event.

Object map of multiple event/handler pairs

Multiple hander/function pairs can be subscribed using an object hash:

ractive.on({
    activate: function () {...},
    select: function () {...}
});

Wildcard pattern handlers

Event names that use a keypath-like name can be subscribed using the pattern-matching wildcard "*" for any name path segment:

ractive.on( 'foo.*', function () {...} );

This example will fire on any event name that starts with foo. - foo.active, foo.select, etc.

This is very useful with event bubbling and auto-prefixed event names that bubble up from components.

Be aware that handlers like widget.* or * will fire for all matching events, including lifecycle events.

Accessing the event object

In addition to the event argument that is passed with proxy events, the event object can be accessed using this.event in the function body of any handler. This object is also present in non-proxy events including lifecycle events, though it includes a more limited set of properties.

Properties on all this.event objects:

Properties only on proxy events:

One useful aspect of this.event is that the name of the event can be determined when wildcards are used:

ractive.on( 'foo.*', function () {
    console.log( this.event.name );
});

Cancelling DOM events

If you return 'false' from a proxy event handler, ractive will automatically call both preventDefault() and stopPropagation() on the original DOM event.

Note that returning false has a dual purpose of both cancelling the view hierarchy event bubbling as well as cancelling the DOM Event if the event was DOM-based.

Unsubscribe

Event handlers are automatically removed if the instance is torn down (e.g. with ractive.teardown()) (which also happens as components are removed due to template/data logic).

You can also unsubscribe event handlers manually using one of two approaches:

var listener = ractive.on( 'activate', function () {
  alert( 'Activating!' );
});
// later...
listener.cancel();

or...

var handler = function () {
  alert( 'Activating!' );
};
ractive.on( 'activate', handler );
// later...
ractive.off( 'activate', handler );

In the second case, note that if you don't specify a handler, all 'activate' handlers will be removed. If you don't specify an event name, all event handlers will be removed from the instance. See ractive.off() for more detail.

The ractive.off() method is chainable for easily replacing subscribtions:

ractive.off( 'activate' ).on( 'activate', function () {...} );

Publish

In addition to the built-in lifecycle events and proxy events, you can fire your own events with ractive.fire().

This is most useful in the context of a component that needs to emit custom events. Here's a (somewhat contrived) example:

var Ticker = Ractive.extend({
  oninit: function () {
    var i = 1;
    this.interval = setInterval( function () {
      this.fire( 'tick', i++ );
    }.bind( this ), 1000 );
  },
  onteardown: function () {
    clearInterval( this.interval );
  }
});
var ticker = new Ticker();
ticker.on( 'tick', function ( i ) {
  console.log( i % 2 ? 'tick' : 'tock' );
});