Declarative Events in AFrameJS

This is an idea borrowed from backbone.js, I take no credit for it. One extremely common pattern in AFrameJS is to have two objects, one we'll call the broadcaster, and the other the listener. The broadcaster is initiated, and then injected into the listener whenever the listener is created. The reason these are called the broadcaster and listener is because the broadcaster broadcasts an event, any event, we'll call it "somethingHappened." When "somethingHappened" is triggered, the listener needs to take some action, it listens for the message. Within AFrame, this all happens using Observables, more documentation can be found under ObservablesMixin. For a long time, the only way to bind events was programatically in an object's bindEvents function, which is verbose.

Fortunately, if using AFrame's class declaration system, events can be declared in the class definition, reducing a lot of the manual labor needed to do this. A little known feature of AFrame is that the prototype chain of every object can be walked, even in Internet Explorer. There are no language tricks used for this, but some housekeeping is needed, AFrame.Class provides this. Because we can walk the prototype chain, we can declare events for on the prototype of each class without problem, even in inherited class structures.

But enough, an example.

Declaring Event Listeners

// The Listener classes declaration. The broadcaster is injected
// in the configuration and imported. Two events are listened for from
// the broadcaster, event1 and event2. 

// The key in the key value pair signifies the event to listen for and the
// name of the object which will trigger the event.
// The value in the key value pair is either a function or a string, if a string,
// the string must be the name of a class function.

// event1 is handled by an inline handler.
// event2 is handled by a class member, the name of the handler is given.
var Listener = AFrame.Class( AFrame.AObject, {
    importconfig: [ 'broadcaster' ],
    events: {
         'event1 broadcaster': function() {
              alert( 'inline event handler used for event1' );
         },
         'event2 broadcaster': 'event2Handler'
    },
    event2Handler: function() {
        alert( 'class function handler used for event2' );
    }
} );

A working example can be found at JSFiddle.

Declaring DOM Event Handlers

This can be used to listen for DOM events as well. Instead of using the "events" key, use "domevents"

var Display = AFrame.Class(AFrame.Display, {
    importconfig: ['broadcaster'],
    domevents: {
        mouseover: function() {
            this.getTarget().css( 'backgroundColor', 'orange' ); 
        },
        mouseout: function() {
            this.getTarget().css( 'backgroundColor', 'white' );
        },
        'click button': 'onButtonClick'
    },
    onButtonClick: function() {
        alert('The Button has been clicked');
    }
});

A working example can be found at JSFiddle.

More documentation can be found under AObject.