2012-08-22 144 views
22

在支持骨幹的應用中,我看到代碼繼續使用<a href="#foo"></a>,而錨點擊由骨幹事件處理程序處理。骨幹路由器導航和錨href

另外,導航到#foo可以通過處理:

Router.history.navigate("foo"); 

我相信後者是優越的方法,因爲它可以方便地移植到和HTML5的pushState的功能。如果我們使用pushState,Backbone將能夠優雅地降級到不支持pushState的瀏覽器的#foo。

由於我還是Backbone的新手,能否有更有經驗和知識淵博的人確認這種情況?

+0

退房這一個:http://stackoverflow.com/questions/9799977/how-to-apply-backbone-router-for-full-路徑不是哈希 – schacki

回答

52

我個人啓用pushState和使用發送所有鏈接點擊到navigateadding a click handler添Branyen的骨幹,樣板採取的做法,除非他們有一個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); 
    } 
}); 

這工作得很好,而且@nickf提到的優點是你不必使用hash/hashbang hack,即使對於不支持pushState的瀏覽器也是如此。

+1

優秀的響應;謝謝。我特別欣賞我剛剛閱讀的github參考。不知道如何,但我希望這是我不必寫的樣板代碼。 –

+8

如果將'app.root'更改爲'Backbone.history.options.root',那麼它將在'app'不在當前上下文中的情況下工作。 –

1

是的我嘗試儘可能多地使用Router.history.navigate,因爲我可以在我的Backbone應用程序。如果用戶在他們的瀏覽器中輸入URL「/ foo」,這也有好處,Backbone正確地路由它。顯然,如果它是外部鏈接或者你不想用Backbone處理的東西,那麼你不應該包含它。

6

你應該把你的鏈接寫成他們的「合適的」地址,也就是說,不要使用哈希來解決特定瀏覽器的一些缺陷。然後,使所有的工作,附加一個點擊處理程序來捕獲點擊這些項目,並將網址傳遞給Backbone.history,然後可以使用pushState或根據需要轉換爲hashbang'd url。例如:

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

克里斯的答案很棒,但有一個補充,它使得它更好。 Backbone.history.navigate()實際上會返回真或假,告訴我們它是否可以在內部路由到它。因此,我們可以跳過data-bypass屬性並執行以下操作來代替:

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