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

发布于 2024-11-30 21:15:04 字数 2152 浏览 1 评论 0原文

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

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

因此,我在路由器子类/对象中重写了 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));
}

这将为每个 hashchange 发布一个公共 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 路由

更新为什么上述程序不起作用:

我们应该在 Router 实例 上绑定 all 事件,但是不在 Router 本身上 - 因此,更改Router.bind('all', ...router.bind('all', ...) 将使上述程序工作

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

少跟Wǒ拽 2024-12-07 21:15:04

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

这里是 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);

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);
就是爱搞怪 2024-12-07 21:15:04

这是我的一个应用程序的一个实例:

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

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');
    }
});
离线来电— 2024-12-07 21:15:04

这就是我正在做的:

@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')

Here's what I'm doing:

@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')
爱你是孤单的心事 2024-12-07 21:15:04

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

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

I faced the problem that the first time a page is loaded, the menu wasn't highlighted as the event came before the binding was initiated.
i fixed this by using the history:

$('#menu li.'+Backbone.history.fragment).addClass('active');
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文