我认为你压倒了错误的事情:这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
;忙碌工作的一部分是这样的:
if (this.iframe) this.navigate(current);
sonavigate
将被调用,但只有当 an<iframe>
用于模拟hashchange
和popstate
事件时才会调用,而 AFAIK 仅在您使用旧版本的 IE 时才会发生。
回到通常的代码路径。我们已经看到它checkUrl
做了一些繁忙的工作和电话loadUrl
,那么它有什么作用呢?loadUrl
这样做:
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;
}
如果您查看 in 中的route
方法和 in 中History
的route
方法,Route
您会发现这handler.callback
是从您的一个路由器调用路由处理程序并触发路由事件的原因。
您要替换的navigate
方法几乎仅由Router
'snavigate
使用:
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
之外没有记录,因此这里的所有内容都可能发生变化。start