【发布时间】:2012-06-27 23:51:55
【问题描述】:
我希望有一个“catch all”路由,该路由在没有其他定义的路由匹配时运行。一种 404 NotFound 错误处理程序。
我试过添加这个,它可以工作,但会阻止其他路由匹配:
this.route(/(.*)/, 'notFound', this.notFound);
以前有人解决过这个问题吗?
【问题讨论】:
标签: javascript backbone.js router
我希望有一个“catch all”路由,该路由在没有其他定义的路由匹配时运行。一种 404 NotFound 错误处理程序。
我试过添加这个,它可以工作,但会阻止其他路由匹配:
this.route(/(.*)/, 'notFound', this.notFound);
以前有人解决过这个问题吗?
【问题讨论】:
标签: javascript backbone.js router
为了完整起见,在此回答。
您可以通过两种方式做到这一点。如问题所示,使用route() 定义正则表达式。但是,由于this bug,您需要通过route() 方法以相反的顺序定义所有路由(顶部的总括)。这会阻止您使用路由哈希,因此(我的)首选方法是:
routes: {
'users/search': 'searchUsers',
'users/:id': 'loadUser',
'*notFound': 'notFound'
}
密钥'*notFound' 实际上可以是任何以* 开头的东西。您只需要 * 之后的字符来防止解析错误。
【讨论】:
routes,以任何特定顺序枚举只是要求它。唯一确定的方法是手动使用route()。
this.route,您有什么想法吗?我认为@machineghost 下面的答案可能是一个更好的解决方案。 backbonejs.org/#History-start
还有另一种可以说更简单/更优雅的方法来解决这个问题。 Backbone.History.start() 根据是否匹配路由返回 true 或 false。所以,如果你这样做:
if (!Backbone.history.start()) router.navigate('404', {trigger:true});
而不是通常的:
Backbone.History.start();
它将与其他答案具有相同的效果。
【讨论】:
router.trigger 位已过时,但逻辑合理! backbonejs.org/#History-start
router.trigger('404') 只需更改为 router.navigate('404', { 'trigger': true }) backbonejs.org/#Router-navigate @evilcelery 您是正确的,它仅在页面加载时调用,这将包括用户和 URL 导航所做的直接位置栏更改。问题是哈希更改是否会触发它。我需要做一些重构才能试一试。它可能不适用于所有情况,但我想知道这些情况是什么。
这个非常小的插件完成了它的工作:https://github.com/STRML/backbone.routeNotFound
这是迄今为止我发现的解决这个问题的最优雅和最强大的方法,但是请记住,使用它会弄乱 Backbone 的内部结构。
【讨论】:
如果没有您当前路由代码的示例,我会假设确保您的 catch all 路线是最后一条路线应该适合您
【讨论】:
route()添加路由,Backbone(至少在历史上)对对象的迭代顺序做了一些无效的假设,没有一致的顺序JavaScript 中的对象键。
route()将它添加为first路由。
只需将其添加为列表中的最后一条路线即可。这样它只会被匹配为后备选项。
【讨论】:
您可以像这样将其破解到主干:
var _loadUrl = Backbone.history.loadUrl;
Backbone.history.loadUrl = function (fragment) {
var result = _loadUrl.apply(Backbone.history, fragment);
// the loadUrl returns false if no route was found.
if(!result){
// call 404 route on router if it exists.
var handler = Backbone.history.handlers.filter( o => o.route.test("404") )
if(handler.length) {
Backbone.history.navigate("/404")
}
}
}
然后在你的路由器中你可以这样做:
var Router = Backbone.Router.extend({
routes: {
"404": "pageNotFound"
},
pageNotFound: function () {
alert("trigger pageNotFound route")
}
});
【讨论】:
我觉得这个不应该通过JavaScript来解决,应该是语言来解决,比如php。在服务器端处理文字,只要有条件就可以响应header,错误号为404
【讨论】:
hashs/hashbangs/pushstate 的客户端路由。服务器端不是答案。