Titanium

Global App Events in Titanium Using Backbone.js

One of the many great features of the Alloy MVC framework is how it uses Backbone.js for events and data-binding.

I’ve posted before on how powerful Alloy data-binding is, but Backbone also drives the event handling in Alloy, enabling controllers to have .on and .off methods, so I can create a new controller instance, open it and pass events back and forth between controllers.

For example, I might have one controller opening another (window-based) one like this:

var newController = Alloy.createController(“login”);
newController.getView().open();

The new controller opens the window view and I might want to have some interaction in that window picked up in the parent — so if it’s a login view and has authenticated successfully, I might want to know that in the parent controller.

I can do this by using the $.trigger method:

function doLogin() {
// login code goes here
$.trigger(“loggedIn”);
}

and in the parent controller I add the following code after I create the controller:

newController.on(“loggedIn”, function(){
// respond to login here
});

In this example, we’re triggering the event in the login controller, and it’s picked up by the parent.

But, you can take this a little further, and use Backbone to add app-level events across the whole codebase.

Let’s look at an example where we have an app that has to clean up after a logout, and maybe that can happen in a few places, due to either the user explicitly logging out, or a session timeout etc.

This is really easy with Backbone events – first let’s create an app helper to assist with managing events:

In Alloy.js, I’ll add the following code:

Alloy.Globals.events = _.clone(Backbone.Events);

Now, we have an object that responds to normal Backbone event methods, so I can now add this handler — maybe in a central (always around controller) like index.js or similar:

Alloy.Globals.events.on(“helloworld”, function(e){
});

Anywhere else in the app, I can run the following code:

Alloy.Globals.events.trigger(“helloworld”);

In this case, the helloworld event is fired, and the handler picks it up and executes. I can turn off the event using the .off method:

Alloy.Globals.events.off(“helloworld”);

or, to remove all events everywhere:

Alloy.Globals.events.off();

Why is this useful?

I can imagine a few scenarios where this would be really helpful — for example:

  1. Your app needs to refresh data in certain situations, or reload data from a server — this could be in a background fetch, or initiated by the user, or due to a change of state somewhere else in the app. Using a Alloy.Globals.events.trigger(“refreshData”); anywhere in the app would do this.
  1. An app may logout in various places — it may time out, or force a logout due to security, or the user may select to logout. Using Alloy.Globals.events.trigger(“logout”); anywhere in the app could run a single handler of code the cleans up any saved settings, deletes data and sends the user back to the login screen.
  1. I might want to have a central app handler, say in index.js or similar, that routes the user to various screens, interfaces, windows or areas of the app. By loosely coupling all the controllers and views (so they can be run independently and communicate via events), I could initiate them from anywhere (e.g. a login or pop-up pin code input).

Personally, I use app level events like this a lot in my apps. I love the fact that I can turn them all off with a single .off method, and prefer to have code in one place and have that “router” handling where the user is sent to next.

I also like that I can add multiple events in the same handler, so:

Alloy.Globals.events.on(“update delete add”, function(e){
// handle the events for update, delete, add here
});

Another way I’ve used app events is in CommonJS modules — for example, I might have an API / REST based module that might want to tell the main app if there’s a connection / network issue (so it can display a message). By adding Backbone events to the module, I can trigger a nonetwork or timeout event — if the hosting apps adds the appropriate handler, it can pick up the event using the .on method and display a message.

You can read more about Backbone.js on the official web site and more about how Alloy uses Backbone in the Alloy documentation

Happy coding!