多条匹配路线

时间:2011-03-07 17:53:12

标签: backbone.js

我有一个定义两个控制器的backbone.js应用程序,控制器都定义了与location.hash匹配的路由模式。我无法解决这两个问题 - 例如。

ManagerController = Backbone.Controller.extend({
   routes: {
      ":name":      "doStuff"
   },

   doStuff : function(name) {
      console.log("doStuff called...");
   }
});

Component1Controller = Backbone.Controller.extend({
   routes: {
      "xyz123":      "doMoreStuff"
   },

   doMoreStuff : function() {
      console.log("doMoreStuff called...");
   }
});

所以如果url是“http://mysite.com/#xyz123”,那么我看到'doStuff()'被调用,或者如果我注释掉那条路线,那么调用'doMoreStuff()'。但不是两个。

我正在使用这种架构,因为我的页面是高度面向组件的,每个组件都定义了自己的Controller。 “组件管理器”还定义了一个控制器,它可以在所有路径上进行一些管理。

我是否应该能够配置两个响应相同路由的控制器?欢呼声,

科林

5 个答案:

答案 0 :(得分:15)

简短回答:不,你做不到。每页一个控制器。

答案很长:当您实例化一个新的Controller时,它会将其路由添加到History单例中。历史单例监视URL的哈希组件,当哈希值发生更改时,它会扫描符合其需要的第一个表达式的路由。然后它会触发与该路由关联的函数(该函数已绑定到声明它的控制器)。它只会发射一次,如果发生冲突,它发射的顺序正式不确定。 (在实践中,这可能是确定性的。)

哲学答案:控制器是一个“视图”对象,它根据URL的哈希组件影响整个页面的表示。其目的是提供用户可以在将来访问的具有书签功能的URL,以便当他访问URL时,他可以从许多预先选择的视图开始。根据您的描述,听起来您正在操纵这个公开曝光的,可手动寻址的项目来操纵视口的不同部分,同时让其他部分独立。这不是它的工作原理。

Backbone的一个好处是,如果你传递一个已经是正则表达式的路径,它将按原样使用它。因此,如果您尝试使用控制器创建布局的可收藏描述(显示模式“A”右上角的组件1,显示模式“B”左上角的组件2等)我可以建议一些替代方案 - 在URL的哈希部分中为每个命名空间分配一个命名空间,并创建忽略其余部分的路由,即

routes: {
    new RegExp('^([^\/]*)/.*$'): 'doComponent1stuff',
    new RegExp('^[^\/]*/([^\/]*)\/.*$': 'doComponent2stuff',
}

了解第一个斜杠之后的第一个项目,第二个斜杠之后的第二个项目等等。您可以完全按照自己的需要对魔法进行编码。

我建议,如果你要对组件的外观和感觉做一些事情,并且你希望它具有合理的持久性,那么你可以查看从一些本地获取和设置其cookie的视图商店;如果它们足够小,那么饼干就足够了。

答案 1 :(得分:7)

我有一个非常类似的问题。目前,骨干在第一条匹配路线后停止。我有一个肮脏的解决方法,我将覆盖Backbone History的loadUrl方法。在这里,我将遍历所有已注册的路由并触发所有匹配路由的回调。

_.extend(Backbone.History.prototype, {
  loadUrl : function() {
    var fragment = this.fragment = this.getFragment();
    var matched = false;
    _.each(this.handlers, function(handler) {
      if (handler.route.test(fragment)) {
        handler.callback(fragment);
        matched = true;
      }
    });
    return matched;
  }
})

哲学上,每页有一个控制器我很好。但是,在基于组件的视图框架中,每个路由有多个视图呈现视图状态的不同部分会很好。

欢迎提出意见。

答案 2 :(得分:1)

我使用了命名空间来处理类似的问题。每个模块都带有自己的模块控制器,但仅限于处理以/ moduleName开头的路由/这样可以独立开发模块。

答案 3 :(得分:0)

我尚未对此进行全面测试,如果您查看Backbone.js源代码,可以在第1449行看到:

// Attempt to load the current URL fragment. If a route succeeds with a
// match, returns `true`. If no defined routes matches the fragment,
// returns `false`.
loadUrl: function(fragment) {
  fragment = this.fragment = this.getFragment(fragment);
  return _.any(this.handlers, function(handler) {
    if (handler.route.test(fragment)) {
      handler.callback(fragment);
      return true;
    }
  });
}

任何方法一旦匹配处理程序路由就会停止(返回“返回true”),只是注释返回并且短路将永远不会发生,并且所有处理程序都将被测试。用带有两个模块的牵线木偶应用程序进行测试,每个模块都有自己的路由器和控制器,同时听到相同的路线和两个模块。

答案 4 :(得分:0)

我认为这是解决问题的最简单方法

路线:{   '':' userGrid',   '用户':' userGrid', }