我正在尝试在执行路由回调之前将路由重定向到另一个路由。我有以下代码:
console.log("file loaded");
(function (History) {
var _navigate = History.prototype.navigate;
_.extend(History.prototype, {
navigate: function (fragment, opts) {
alert("adad");
return _navigate.call(this, fragment, opts);
}
});
})(Backbone.History);
此代码包装Backbone.History.navigate
方法,并在方法调用上显示警报。但是当我改变路线时,这个警报永远不会出现。
console.log
行只是为了确保在backbone.js之后加载了文件。
此代码有什么问题?
答案 0 :(得分:2)
我认为你压倒了错误的事情:navigate
没有像你想象的那样被使用。
让我们看一下Backbone.history.start
的一部分:
// Start the hash change handling, returning `true` if the current URL matches
// an existing route, and `false` otherwise.
start: function(options) {
//...
if (this._hasPushState) {
Backbone.$(window).on('popstate', this.checkUrl);
} else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
Backbone.$(window).on('hashchange', this.checkUrl);
} else if (this._wantsHashChange) {
this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
}
您会看到在Backbone中处理路由的所有各种方法都是通过checkUrl
而不是navigate
。 checkUrl
方法做了一些繁忙的工作并调用了loadUrl
;一个part of the busy work is this:
if (this.iframe) this.navigate(current);
所以navigate
会被调用,但只有当<iframe>
用于模拟hashchange
和popstate
事件时才会被调用,AFAIK只会在您使用旧版时发生IE的版本。
回到通过代码的通常路径。我们已经看到checkUrl
做了一些繁忙的工作并致电loadUrl
那么这又做什么? loadUrl
does this:
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;
}
如果查看route
method in History
和route
method in Route
,您会看到handler.callback
是从您的某个路由器调用路由处理程序并触发路由事件。
您要替换的navigate
方法几乎仅由Router
's navigate
使用:
navigate: function(fragment, options) {
Backbone.history.navigate(fragment, options);
return this;
}
如果要在调用路由处理程序之前重定向,可以使用以下内容替换loadUrl
:
(function(History) {
var _loadUrl = History.prototype.loadUrl;
_.extend(History.prototype, {
loadUrl: function() {
var args = [].slice.apply(arguments);
args[0] = this.getFragment(args[0]);
// If args[0] is the fragment that you want to
// redirect then replace it here or do whatever
// needs to be done.
return _loadUrl.apply(this, args);
}
});
})(Backbone.History);
演示:http://jsfiddle.net/ambiguous/e4KYK/
总的来说,我认为你最好在普通路由处理程序中处理重定向:当调用违规路由时,只需在任何路由器上调用navigate
就可以了。
请注意Backbone.History
以外的{{1}}未记录,因此此处的所有内容都可能发生变化。