перенаправление на другой маршрут

Я пытаюсь перенаправить маршрут на другой, прежде чем обратный вызов маршрута будет выполнен. У меня есть следующий фрагмент кода:

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 line - это просто убедиться, что файл был загружен после магистрали.js.

что не так с этим кодом?

1 ответов


я думаю, вы переопределяете неправильную вещь: это 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);
  }

вы увидите, что все различные способы обработки маршрутизации в магистрали проходят через checkUrl, а не navigate. The checkUrl метод делает немного занятой работы и вызывает loadUrl; один часть напряженной работы это:

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

так navigate будет вызываться, но только когда <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;
}

если вы посмотрите на route метод History и route метод 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 не документируется за пределами start метод так что все здесь может измениться.