Backbone Routes and History

Backbone Routes –

As backbone being a platform which supports the client side, we also in need for a traditional Request/Response website. outesWe fully expect the back and forward history navigation to work. With the stateless nature of the traditional website, this was very easy to implement. The browser needed only to keep track of the previously requested URLs and request them again when the user asks for them Single Page Applications built using JavaScript are stateful and will require programmer intervention to allow this appearance of functioning history. Luckily for us, Backbone provides mechanisms to make this process easier. The URL of the application should change when the content on the screen changes. We also like to share URLs with other people, as well as bookmark these URLs for later browsing. Typically, traditional web apps have a URL that points to a resource on the server, beginning with a forward slash. Every time a new page is requested, the server responds with an entirely new page based on that URL.
Luckily in backbone we are able to achieve this goal with the help of ‘router’ and ‘history’. So, let us discuss about them.
Router:
Backbone routers are used for routing your applications URL’s when using hash tags(#). In the traditional MVC sense they don’t necessarily fit the semantics. Though a Backbone “router” is still very useful for any application that needs URL routing/history capabilities.Let us get an idea of router through a diagram.

router

Defined routers should always contain at least one route and a function to map the particular route to. In the example below we are going to define a route that is always called. Routes interpret anything after “#” tag in the URL. All links in the application should target “#/action” or “#action”. During page load, after the application has finished creating all of its routers, be sure to call Backbone.history.start(), or Backbone.history.start({pushState: true}) to route the initial URL. Let us see a basic example.

var AppRouter = Backbone.Router.extend({
        routes: {
            "*actions": "defaultRoute" 
        }
    });
    // Initiate the router
    var app_router = new AppRouter;
    app_router.on('route:defaultRoute', function(actions) {
        alert(actions);
    })

    // Start Backbone history a necessary step for bookmarkable URL's
    Backbone.history.start();

extend:
Now create a custom router class. Define actions that are triggered when certain URL fragments are matched, and provide a routes hash that pairs routes to actions.

var myrouter = Backbone.Router.extend({
  routes: {
    "help":                 "help",    
    "search/:query":        "search" 
  },
  help: function() {
    ...
  },
  search: function(query) {
    ...
  }
});

routes:
The routes hash maps URLs with parameters to functions on router, similar to the View’s events hash. Routes can contain parameter parts, :param, which match a single URL component between slashes; and splat parts *splat, which can match any number of URL components. Part of a route can be made optional by surrounding it in parentheses (/:optional).

When the visitor presses the back button, or enters a URL, and a particular route is matched, the name of the action will be fired as an event, so that other objects can listen to the router, and be notified. In the following example, visiting #help/uploading will fire a route:help event from the router.

routes: {
  "help/:page":         "help",
  "download/*path":     "download",
  "folder/:name":       "openFolder",
  "folder/:name-:mode": "openFolder"
}
router.on("route:help", function(page) {
  ...
});

route:
Manually creates a route for the router, The route argument may be a routing string or regular expression. Each matching capture from the route or regular expression will be passed as an argument to the callback. The name argument will be triggered as a “route:name” event whenever the route is matched. If the callback argument is omitted router[name] will be used instead.

initialize: function(options) {
  this.route("chapter/:number", "chapter", function(number){ ... });
    this.route(/^(.*?)\/open$/, "open");
},
open: function(id) { ... }

Dynamic Routing
Most conventional frameworks allow you to define routes that contain a mix of static and dynamic route parameters.

  var AppRouter = Backbone.Router.extend({
        routes: {
            "posts/:id": "getPost",
            "*actions": "defaultRoute" // Backbone will try match the route above first
        }
    });
    // Instantiate the router
    var app_router = new AppRouter;
    app_router.on('route:getPost', function (id) {
        // Note the variable in the route definition being passed in here
        alert( "Get post number " + id );   
    });
    app_router.on('route:defaultRoute', function (actions) {
        alert( actions ); 
    });
    // Start Backbone history a necessary step for bookmarkable URL's
    Backbone.history.start();

navigate:
Whenever an application has to be save as a URL, call navigate in order to update the URL. If we want to also call the route function, set the trigger option to true. To update the URL without creating an entry in the browser’s history, set the replace option to true.

openPage: function(pageNumber) {
  this.document.pages.at(pageNumber).open();
  this.navigate("page/" + pageNumber);
}
# Or ...
app.navigate("help/troubleshooting", {trigger: true});
# Or ...
app.navigate("help/troubleshooting", {trigger: true, replace: true});

history:
History serves as a global router (per frame) to handle hash-change events or push-state, match the appropriate route, and trigger callbacks. we shouldn’t ever have to create one of these our-self since Backbone.history already contains one.
pushState support exists on a purely opt-in basis in Backbone. Older browsers that don’t support pushState will continue to use hash-based URL fragments, and if a hash URL is visited by a pushState-capable browser, it will be transparently upgraded to the true URL.using real URLs requires web server to be able to correctly render those pages, so back-end changes are required as well. For full search-engine crawl-ability, it’s best to have the server generate the complete HTML for the page. but if it’s a web application, just rendering the same content would have for the root URL, and filling in the rest with Backbone Views and JavaScript works fine.
start:
When all of Routers have been created, and all of the routes are set up properly, call Backbone.history.start() to begin monitoring hash-change events, and dispatching routes.to use HTML5 pushState support in application, use Backbone.history.start({pushState: true}). If you’d like to use push-state, we also can add {hashChange: false} to the options.
If our application is not being served from the root url / of your domain, be sure to tell History where the root really is, as an option:

 Backbone.history.start({pushState: true, root: "/public/search/"})

When called, if a route succeeds with a match for the current URL, Backbone.history.start() returns true. If no defined route matches the current URL, it returns false.
If the server has already rendered the entire page, and not to trigger initial route when starting History, pass silent: true.
Because hash-based history in Internet Explorer relies on an , be sure to only call start() after the DOM is ready.

$(function(){
  new WorkspaceRouter();
  new HelpPaneRouter();
  Backbone.history.start({pushState: true});
});

Some related articles :

1>Introduction to Backbone.js

2>Models in Backbone.js

3>Understanding view in Backbone.js

4>Collections in Backbone.js

5>Underscore Methods in Backbone.js

6>Templates In Backbone.js

7>WHY SHOULD WE USE SERVER SIDE IN BACKBONE.JS?

8>Backbone.js at a glance

We will have other detail of Backbone features in our later articles. So please look for the same.
If you find this article helpful, you can connect us in Google+ and Twitter.