Backbone.js - Routing made simple
Backbone has a very nice Router implementation that makes it easy to map client-side routes to Javascript methods.
APP.Router = Backbone.Router.extend({ routes: { "new": "newNote", ":id": "editNote", "": "home" }, home: function() { APP.appView.home(); }, newNote: function() { APP.appView.newNote(); }, editNote: function( id ) { APP.appView.editNote( id ); } });
We also have the History object to start listening to routes and to switch from using the old fashioned hashChange event to the HTML5 pushState that is supported in modern browsers.
// Start the history // using HTML5 push state Backbone.history.start({pushState: true});
With these things at our service enabling client-side routing in our app is easy as breeze right ? Wrong. It’s not that simple because responding to url changes on the client-side is both stateful and stateless.
If the user writes an url in the browser or hits the refresh button it will cause a stateless request to our application and the desired state for the route needs to be built up from scratch.
However, if the user hits the back and forward buttons in our app that change is stateful and the correct state needs to be changed from the previous state that still exists in memory.
The stateful scenario is usually handled by resetting all the Backbone views and then building the desired state from scratch.
This works all dandy but becomes hard for complex applications with many views that needs to be resetted.
// Close all views view1.close(); view2.close(); view3.close(); // TODO: Finally we can respond to the route
A better solution to this problem is to implement a view manager that we use to register all views that are initialized.
// initialize and register views var view = new MyView; viewManager.register( view );
We also implement our views with a dispose method that knows how to reset the view, read my last blog post for more information about creating a dispose method.
var MyView = Backbone.View.extend({ dispose: function() { // TODO: Dispose logic here } });
When it comes time to reset the application the view manager calls dispose on all the views and closes them all at once.
// Now we can reset all the views // at once very easily viewManager.reset();
This is great because now we have abstracted this behavior and it can be handled in one call on the view manager. This also requires a very simple logic that already is available in this repository on Github.