【问题标题】:Highlighting current navigation state in Backbone.js application在 Backbone.js 应用程序中突出显示当前导航状态
【发布时间】:2011-10-31 22:37:49
【问题描述】:

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

当单击#home 和其他链接时,Backbone.js 会触发单个事件,例如route:home、...route:some-other。我看不到任何会为每个 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));
}

这将为每个 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 route

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

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

【问题讨论】:

  • 在骨干网 0.5.x 中,您可以将 all 事件绑定到路由器,传递给您的处理程序的第一个参数将是路由
  • @ant_Ti - 将其作为答案而不是评论发布,这样您就可以获得荣誉。
  • @ant_Ti 我不知道为什么我错过了看到你的评论。我试图将“全部”绑定到路由器,但它似乎不是那样工作的。我也浏览了源代码,也找不到触发任何“全部”事件的路由器。我添加了简单的 sn-p 来证明这一点。您可以添加一些代码(请作为答案)
  • 是的,当然!这里是exemple on jsfiddle
  • 谢谢。我对Router而不是它的实例router进行绑定并没有让我感到震惊。有了这个,我得到了路由更改事件,例如route:home仅适用于已知路由(因为仅对它们进行触发)。通过我目前的小修复,我也可以处理我需要的未知链接(404)(但在 OP 中没有提及)。请添加您的评论/程序作为答案。我会接受的。

标签: navigation backbone.js highlighting


【解决方案1】:

这就是我正在做的事情:

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      在主干 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);
      

      【讨论】:

      • 就像其他人的参考:绑定到 'all' 事件会导致处理函数接收路由更改事件,如 route:home,但仅适用于已知路由(因为仅对它们进行触发)
      • 问题,这会在所有内容渲染完毕后触发?
      • 老问题,但是有人吗?我有一个查询...我已经成功完成了上述部分,但它在我的所有导航中触发了 2 次...第一个给出正确的信息,第二个总是空白...任何想法???
      【解决方案4】:

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

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

      【讨论】:

      • 我也有类似的高亮逻辑(也可以高亮主菜单和子菜单)。但是all 事件绑定的问题在于它只会接收已知路由。我想知道所有路由更改(简单地说,每个哈希更改)。这对于显示一些 404 错误很有用。
      • 对于“404”路线检测,我将其添加为我的最后一条路线:"*path": "page404Error"
      • 老问题,但是有人吗?我有一个查询...我已经成功完成了上述部分,但它在我的所有导航中触发了 2 次...第一个给出正确的信息,第二个总是空白...任何想法???
      • 听起来您在其他地方也有触发它的代码。在上面的代码中添加一个警报,如果警报触发两次,你就知道这是原因,如果没有,其他地方有代码。
      猜你喜欢
      • 1970-01-01
      • 2012-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-02
      • 2014-01-24
      • 2017-01-31
      相关资源
      最近更新 更多