2013-02-12 9 views
7

Sto provando a reindirizzare il percorso a un altro prima che venga eseguita la richiamata della rotta. Ho seguito pezzo di codice:reindirizzare il percorso a un altro

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

Questo codice avvolge Backbone.History.navigate metodo, e mostrando avviso la chiamata al metodo. Ma questo avviso non compare mai quando cambio rotta.

La riga console.log è solo per assicurarsi che il file sia stato caricato dopo backbone.js.

Cosa c'è di sbagliato con questo codice?

+1

Suppongo che tu abbia chiamato Backbone.history.start() da qualche parte? – WiredPrairie

+0

si l'ho fatto - le mie opinioni stanno cambiando, non ho idea del perché questo non funzioni – user606521

+0

Deve essere qualcos'altro.Ho appena inserito il tuo codice in un progetto Backbone che ho aperto, e sono stato immediatamente infastidito dall'avviso di 'adad' non appena ho navigato. :) Ho il codice di identificazione del codice boilerplate per il codice "Navigate" inserito nella mia app, che può cambiare il comportamento. – WiredPrairie

risposta

2

Penso che tu stia ignorando la cosa sbagliata: che lo navigate non è usato nel modo in cui pensi che sia.

Guardiamo parte di 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); 
    } 

Vedrete che tutti i vari modi di gestire il routing in Backbone passano attraverso checkUrl piuttosto che navigate. Il metodo checkUrl svolge un po 'di lavoro intenso e chiama loadUrl; uno part of the busy work is this:

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

così navigate saranno chiamati, ma solo quando un viene utilizzato per simulare hashchange e popstate eventi e per quanto ne so che si verifica solo quando si utilizza una versione precedente di Internet Explorer.

Torna al solito percorso attraverso il codice. Abbiamo visto che checkUrl svolge un po 'di lavoro e chiama loadUrl quindi cosa fa? 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; 
} 

Se si guarda al route method in History e route method in Route vedrai che handler.callback è quello che chiama il gestore percorso da uno dei vostri router e attiva l'evento di routing.

Il metodo navigate che si sta sostituendo è praticamente utilizzato solo da Router's navigate:

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

Se si desidera reindirizzare prima del gestore percorso si chiama, è possibile sostituire loadUrl con qualcosa di simile:

(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/

Nel complesso credo che sarebbe meglio disattivando il reindirizzamento in un normale gestore di percorsi: quando viene chiamato il percorso incriminato, è sufficiente chiamare lo navigate su qualunque router sia a portata di mano.


Tenete a mente che Backbone.History non è documentata al di là del start method quindi tutto qui è soggetto a modifiche.

+0

perfetto, funziona per me, grazie – user606521

Problemi correlati