我们在同一个MVC应用程序中有多个单页面应用程序。我们正在使用Backbone / Marionette,并且路由似乎不起作用(默认路由操作永远不会被触发)。
代码:
QaApp.module("QaApp", function (Mod, App, Backbone, Marionette, $, _) { QaApp.Router = Marionette.AppRouter.extend( { appRoutes: { '' : 'subscribe', ':id': 'subscribe', '/qa/index/:id': 'subscribe' } }); var Api = { subscribe: function (id) { //never fires console.log("subscribing with id = " + id); QaApp.Lightstreamer.Do('subscribeUpdate', { adapterName: 'QaAdapter', field: ['jsonString', 'firstData'], parameterValue: id, onUpdate: load }); }, load: function (data) { var question = new QaApp.Question({ id: data.id, collection: data.messages }); var questionView = new QaApp.QuestionView(question); QaApp.page.show(questionView); } }; QaApp.addInitializer(function () { var router = new QaApp.Router( { controller: Api }); console.log(router.appRoutes); }); });
标准路由器似乎假设您的根网址为http://localhost
,或者如果不是,则路由是#之后的任何内容(在任何情况下都找不到好的文档)。
所以,对我们来说,当你登陆页面时,网址可能是:
控制器为“qa”的 http://localhost/qa/index/1
,视图为“index”,id为1.
我希望我的“订阅”操作触发此默认网址并将“id”作为参数。
我应该使用哪条路线?
注意:根据this post,我已经确认在初始化程序运行后调用了Backbone.history.start()。
另请注意:在appRoutes下面是我尝试的所有不同路线。我知道我只需要一个,只要我能找到合适的那个。
提前致谢!
更新:单步执行主干代码,似乎“this.handlers”是一个空数组,所以看起来网址永远不会匹配。
更新基于更新的答案:传入root确实让骨干认识到我在根,所以我更接近,但在下面的段中,“fragment”是“”,this.handlers是一个0长度数组,“匹配”返回false:
loadUrl: function (fragmentOverride) {
var fragment = this.fragment = this.getFragment(fragmentOverride);
var matched = _.any(this.handlers, function (handler) {
if (handler.route.test(fragment)) {
handler.callback(fragment);
return true;
}
});
return matched;
}
最终更新:处理程序是空的是问题,结果是由于页面部分加载了backbone.js的第二个实例 - 所以一个实例设置了处理程序而另一个实例没有
谢谢,大卫!
答案 0 :(得分:5)
如果您不希望在网址中包含“#”,则需要将pushState与
一起使用Backbone.history.start({pushState: true });
请注意,要使其工作,您的Backbone应用程序可以生成的每个URL必须存在于服务器上。换句话说,服务器必须为您的应用返回可以访问的每个网址的有效页面。每个网址的内容不必相同(您可以发送包含应用的相同index.html
内容,并让Backbone处理应显示的内容),但需要将某些内容发送给客户端。
根据评论进行编辑:
它没有按预期运行的原因是因为用于启动Backbone应用程序的任何页面默认为其根URL,因此不会执行任何路由。尝试在启动历史记录时设置root
属性(请参阅http://backbonejs.org/#History-start)