Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Highlighting current navigation state in Backbone.js application

I want to highlight the current navigation state. Like if the hashchange is #home, I want to style the 'Home' menu link differently and similarly other links.

Backbone.js fires individual events like route:home,... route:some-other when the #home and other links are clicked. I could not see any common event that will be fired for every hashchange. With this I m required to write the state highlight logic by binding to all the route events, which I think is not good solution.

So, I've overridden Backbone.Router.route in my router sub class/object, like

// override backbone' Router.route method to publish 
// common 'route_change' event for any hash change
route : function(route, name, callback) {
    Backbone.history || (Backbone.history = new Backbone.History);
    if (!_.isRegExp(route)) route = this._routeToRegExp(route);
    Backbone.history.route(route, _.bind(function(fragment) {
        var args = this._extractParameters(route, fragment);
        callback.apply(this, args);
        this.trigger.apply(this, ['route:' + name].concat(args));

        // ADDED BY: ManiKanta G
        // name: route method
        // fragment: route path
        // args: any additional args
        this.trigger.apply(this, ['route_change'].concat(name, fragment, args));
    }, this));
}

This will publish a common route_change event for every hashchange and passing the name, fragment, and other args using which I m highlighting the state all in a single place.

My question is do I have to override the Backbone method like this or is there any build in mechanism I can use here. If not, I would like to see similar behaviour in Backbone.js

Edit: sample program

Router = Backbone.Router.extend({
    routes : {
        '': 'root', 
        'home': 'home',
        'about':'about'
    },

    // app routing methods
    root: function () { console.log('root route');  },
    home: function () { console.log('home route');  },
    about: function () { console.log('about route'); }

});

Router.bind('all', function () {
    console.log('all route...');
});

router = new Router();

and, navigating using the above router:

router.navigate('home', true);

output: home route

Update on why the above program is not working:

we should bind for all event on Router instance, but not on the Router itself - so, changing the Router.bind('all', ... to router.bind('all', ...) will make the above program work

like image 243
manikanta Avatar asked Aug 22 '11 07:08

manikanta


People also ask

What is backbone JS?

Backbone.js. Backbone.js gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface. The project is hosted on GitHub , ...

How to update and save the application as URL in backbone?

The Backbone.js navigate method is used to update and save the application as URL. It can also be done by calling the route function. fragment: It specifies the name of the parameter in which URL will be displayed. options: It specifies the options such as trigger and replace to call the route function and to update the URL. Let's take an example.

How do I update views in a backbone app?

In a finished Backbone app, you don't have to write the glue code that looks into the DOM to find an element with a specific id , and update the HTML manually — when the model changes, the views simply update themselves.

What is the use of backbone in backend?

Backbone.js Backbone.js gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.


2 Answers

In backbone 0.5.x you can bind all event to router instance and the first argument pass to your handler will be route

Here is exemple on jsfiddle, reproduced here:

var dummy = Backbone.Router.extend({
    defaultPage: 'messages',

    routes: {
        '': 'index',
        'index': 'index',
        'mailbox': 'mailbox'
    },

    index: function() {
        // code here
    },

    mailbox: function() {
        // code here
    }
});

var router = new dummy();

router.bind('all', function(route) {
    document.write('triggered: ' + route + '<br/>');
});

router.navigate('index', true);
router.navigate('mailbox', true);
like image 86
ant_Ti Avatar answered Oct 16 '22 09:10

ant_Ti


Here 's a live example from one of my apps:

routes.bind('all ', function(route, section) {
    var $el;
    route = route.replace('route: ', '');

    $el = $('#nav - ' + route);

    // If current route is highlighted, we're done.
    if ($el.hasClass('selected')) {
        return;
    } else {
        // Unhighlight active tab.
        $('#menu li.selected').removeClass('selected');
        // Highlight active page tab.
        $el.addClass('selected');
    }
});
like image 25
Mauvis Ledford Avatar answered Oct 16 '22 08:10

Mauvis Ledford