突出显示Backbone.js应用程序中的当前导航状态

时间:2011-08-22 07:34:25

标签: navigation backbone.js highlighting

我想突出显示当前的导航状态。就像哈希变换是#home一样,我想以不同的方式设置“主页”菜单链接的样式,并且类似于其他链接。

当单击route:home和其他链接时,Backbone.js会触发route:some-other,... #home等单个事件。我看不到每个hashchange都会触发的任何常见事件。有了这个,我需要通过绑定到所有路由事件来编写状态突出显示逻辑,我认为这不是一个好的解决方案。

所以,我在路由器子类/对象中覆盖了Backbone.Router.route,比如

// 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));
}

这将为每个哈希转换发布一个常见的route_change事件,并传递namefragment和其他args使用我将突出显示状态全部放在一个的地方。

我的问题是我是否必须像这样覆盖Backbone方法,或者我可以在这里使用任何构建机制。如果没有,我想在Backbone.js中看到类似的行为

编辑:示例程序

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();

并使用上述路由器进行导航:

router.navigate('home', true);

输出:home route

关于上述程序无效的原因

更新

我们应该在all上绑定Router instance个事件,而不是在Router本身绑定 - 所以,将Router.bind('all', ...更改为router.bind('all', ...)会使上述情况发生变化计划工作

4 个答案:

答案 0 :(得分:7)

在主干0.5.x中,您可以将all事件绑定到路由器实例,并且传递给您的处理程序的第一个参数将是路由

以下是exemple on jsfiddle,转载于此处:

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);

答案 1 :(得分:2)

以下是我的其中一个应用的实例:

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');
    }
});

答案 2 :(得分:0)

这就是我正在做的事情:

@router.bind 'all', (route) ->
  # this triggers twice for every route; ignore the second time
  return if route == "route"

  # ex: route="route:home", name="home", href="#home"
  name = route.replace('route:', '')

  # remove the active class on all of the current nav links
  $("#menu li.active").removeClass('active')

  # add it back to the link that has an href that ends in `name`
  $("#menu a[href$='#{name}']").parent().addClass('active')

答案 3 :(得分:-1)

我遇到的问题是,第一次加载页面时,菜单没有突出显示,因为事件在启动绑定之前发生。 我通过使用历史来解决这个问题:

$('#menu li.'+Backbone.history.fragment).addClass('active');