2012-08-22 32 views
22

In un'app abilitata per backbone, ho visto il codice che continua a utilizzare <a href="#foo"></a>, mentre il clic di ancoraggio è gestito da un gestore di eventi backbone.Backbone Router navigate e anchor href

In alternativa, la navigazione verso #foo può essere gestito da:

Router.history.navigate("foo"); 

Credo che il secondo è l'approccio superiore perché permette una facile migrazione da e per la funzionalità pushState di HTML5. E se usiamo pushState, Backbone sarebbe in grado di degradarsi con grazia a #foo per i browser che non supportano pushState.

Dato che sono ancora nuovo a Backbone, qualcuno più esperto e competente può confermare che questo è il caso?

+0

Partenza questo: http://stackoverflow.com/questions/9799977/how-to-apply-backbone-router-for-full- path-not-a-hash – schacki

risposta

52

Personalmente ho pushState abilitato e utilizzare l'approccio adottato nella Tim Branyen spina dorsale-boilerplate di adding a click handler che invia tutti i clic sui link per navigate meno che non abbiano un attributo data-bypass:

$(document).on("click", "a:not([data-bypass])", function(evt) { 
    var href = { prop: $(this).prop("href"), attr: $(this).attr("href") }; 
    var root = location.protocol + "//" + location.host + Backbone.history.options.root; 

    if (href.prop && href.prop.slice(0, root.length) === root) { 
    evt.preventDefault(); 
    Backbone.history.navigate(href.attr, true); 
    } 
}); 

Questo funziona abbastanza bene e come menzioni @nickf ha il vantaggio che non devi usare hash hash/hashbang, anche per i browser che non supportano pushState.

+1

Ottima risposta; Grazie. Apprezzo soprattutto il riferimento github, che ho appena letto. Non so come, ma mi auguro che questo sia il codice di caldaia che non devo scrivere. –

+8

Se si modifica "app.root" in "Backbone.history.options.root", funzionerà dove "app" non si trova nel contesto corrente. –

1

Sì, provo ad utilizzare tanto Router.history.navigate come posso nelle mie app Backbone. Questo ha anche il vantaggio di se l'utente digita l'URL "/ foo" nel proprio browser, Backbone lo instrada correttamente. Ovviamente, se si tratta di un collegamento esterno o qualcosa che non si desidera gestire con Backbone, non è necessario includerlo.

6

Dovresti scrivere i tuoi link come indirizzi "corretti", cioè non con l'hash che è solo un trucco per aggirare alcune carenze di un particolare browser. Per fare in modo che tutto funzioni, collega un gestore di clic per catturare i clic su questi elementi e passa gli URL a Backbone.history, che può quindi utilizzare pushState o convertire in un url hashbang'd se necessario. Per esempio:

$(document).on('click', 'a[href^="/"]', function (event) { 
    // here, ensure that it was a left-mouse-button click. middle click should be 
    // allowed to pass through 
    event.preventDefault(); 
    Backbone.history.navigate(this.href); 
}); 
2

La risposta di Chris è fantastica, ma c'è un'aggiunta che lo rende ancora migliore. Backbone.history.navigate() restituisce effettivamente true o false dicendoci se è possibile instradarlo internamente. Possiamo quindi ignorare l'attributo data-bypass e procedere come segue invece:

$(document).on("click", "a", function(evt) { 
    var href = { prop: $(this).prop("href"), attr: $(this).attr("href") }; 
    var root = location.protocol + "//" + location.host + Backbone.history.options.root; 

    if (href.prop && href.prop.slice(0, root.length) === root) { 
    if (Backbone.history.navigate(href.attr, true)) { 
     evt.preventDefault(); 
    } 
    } 
});