将路线重定向到另一个

时间:2013-02-12 19:12:32

标签: backbone.js backbone-routing

我正在尝试在执行路由回调之前将路由重定向到另一个路由。我有以下代码:

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之后加载了文件。

此代码有什么问题?

1 个答案:

答案 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而不是navigatecheckUrl方法做了一些繁忙的工作并调用了loadUrl;一个part of the busy work is this

  if (this.iframe) this.navigate(current);

所以navigate会被调用,但只有当<iframe>用于模拟hashchangepopstate事件时才会被调用,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 Historyroute 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}}未记录,因此此处的所有内容都可能发生变化。