2013-02-12 24 views
7

Próbuję przekierować trasę do innej, zanim zostanie wykonane wywołanie zwrotne trasy. Mam następujący fragment kodu:Przekieruj trasę do innej

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); 

Kod ten otacza Backbone.History.navigate metody i pokazano wpisu na wywołanie metody. Ale ten alert nie pojawia się, gdy zmieniam trasę.

Linia console.log ma na celu upewnienie się, że plik został załadowany po pliku backbone.js.

Co jest nie tak z tym kodem?

+1

Zakładam, że nazwałaś gdzieś Backbone.history.start()? – WiredPrairie

+0

Tak, zrobiłem - moje poglądy się zmieniają, nie mam pojęcia, dlaczego to nie działa – user606521

+0

To musi być coś innego.Po prostu podłączyłem twój kod do projektu Backbone, który mam otwarty, i natychmiast zostałem zirytowany przez alert adad, jak tylko nawigowałem. :) Mam kodowany znacznik zakotwiczenia kodu do kodu "Nawiguj" podłączonego do mojej aplikacji, co może zmienić zachowanie. – WiredPrairie

Odpowiedz

2

Myślę, że przesłoniłeś niewłaściwą rzecz: to, że navigate nie jest używane tak jak myślisz.

Spójrzmy na części 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); 
    } 

Zobaczysz, że wszystkie różne sposoby obsługi routingu w Backbone przejść checkUrl zamiast navigate. Metoda checkUrl wykonuje trochę zajętej pracy i wywołuje loadUrl; jeden part of the busy work is this:

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

tak navigate zostanie wywołana, ale tylko wtedy, gdy jest używany do symulacji hashchange i popstate wydarzenia i AFAIK, że tylko się dzieje, gdy używasz starszej wersji IE.

Powrót do zwykłej ścieżki za pośrednictwem kodu. Widzieliśmy, że checkUrl wykonuje jakąś pracowitą pracę i dzwoni pod numer loadUrl, więc co to oznacza? 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; 
} 

Jeśli spojrzeć na route method in History a route method in Route zobaczysz, że handler.callback co wywołuje obsługi trasy z jednego z routerów i wyzwala zdarzenie routingu.

Sposób navigate że jesteś zastąpienia jest dość dużo używany tylko przez Router's navigate:

navigate: function(fragment, options) { 
    Backbone.history.navigate(fragment, options); 
    return this; 
} 

Jeśli chcesz przekierować przed obsługi trasa nazywa, można zastąpić loadUrl z czymś takim:

(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); 

Demo: http://jsfiddle.net/ambiguous/e4KYK/

Ogólnie myślę, że byłbyś lepiej wyłączenie obsługi przekierowania w normalnym procederze obsługi trasy: gdy wywoływana jest przeszkadzająca trasa, wystarczy zadzwonić pod numer navigate na jakimkolwiek routerze, który jest przydatny.


Należy pamiętać, że nie jest udokumentowana Backbone.History poza start method więc tutaj wszystko może ulec zmianie.

+0

doskonały, to działa dla mnie, dzięki – user606521

Powiązane problemy