Search code examples
backbone.jsbrowser-history

Which one should I use? Backbone.js Router.navigate and window.location.hash


I began learning Backbonejs recently, by reading a book. and I feel a little bit confuse about this issue.Here is a Router:

define(['views/index', 'views/login'], function(indexView, loginView) {

    var SelinkRouter = Backbone.Router.extend({

        currentView: null,

        routes: {
            'home': 'home',
            'login': 'login'
        },

        changeView: function(view) {
            if(null != this.currentView)
                this.currentView.undelegateEvents();
            this.currentView = view;
            this.currentView.render();
        },

        home: function() {
            this.changeView(indexView);
        },

        login: function() {
            this.changeView(loginView);
        }
    });

    return new SelinkRouter();
});

and this is the boot method of a application:

define(['router'], function(router) {

    var initialize = function() {
        // Require home page from server
        $.ajax({
            url: '/home',          // page url
            type: 'GET',           // method is get
            dataType: 'json',      // use json format
            success: function() {  // success handler
                runApplicaton(true);
            },
            error: function() {    // error handler
                runApplicaton(false);
            }
        });
    };

    var runApplicaton = function(authenticated) {

        // Authenticated user move to home page
        if(authenticated) window.location.hash='home';
                          //router.navigate('home', true); -> not work

        // Unauthed user move to login page
        else window.location.hash='login';
             //router.navigate('login', true); -> not work

        // Start history
        Backbone.history.start();
    }

    return {
        initialize: initialize
    };
});

My question is about the runApplication part. The example of the book that I read passed router into module just like this, but it used window.location.hash = "XXX", and the router wasn't touched at all.

I thought the "navigate" method would make browser move to the page I specified, but nothing happened. Why?

And for the best practice sake, what is the best way to achieve movement between pages(or views)?

thanks for any ideas.


Solution

  • According to the documentation, if you also want to call the function belonging to a specific route you need to pass the option trigger: true:

    Whenever you reach a point in your application that you'd like to save as a URL, call navigate in order to update the URL. If you wish 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.

    your code should look like:

    if(authenticated)
        router.navigate('home', {trigger: true});
    

    Once your router is created, you also have to call

    Backbone.history.start();
    

    Backbone.history.start([options])

    When all of your Routers have been created, and all of the routes are set up properly, call Backbone.history.start() to begin monitoring hashchange events, and dispatching routes.

    Finally the runApplication logic will be something similar to this:

    var runApplicaton = function(authenticated) {
    
        var router = new SelinkRouter();
        // Start history
        Backbone.history.start();
    
        // Authenticated user move to home page
        if(authenticated)
            router.navigate('home', true);
        // Unauthed user move to login page
        else
            router.navigate('login', true);
    }