2012-08-22 19 views
6

我嘗試使用pushState選項製作帶有Rails 3.2和Backbone.js的單頁應用程序,但遇到了一些我不明白的東西。如何處理單個頁面應用中的非根URL?

如果我加載應用程序的根URL(/),一切正常:Rails返回一個帶JS的HTML佈局,它引導Backbone,它爲JSON實體制作一些XHR並呈現內容。

但是,如果我開始使用應用程序從非根URL(例如,通過在瀏覽器的地址欄中手動鍵入它),那麼Rails會嘗試使用從routes.rb中他們的路由規則來處理此請求 - 這是錯誤的,原因這是一個「骨幹」路線。在這種情況下,如何加載頁面和引導Backbone來處理這個URL?

回答

14

最後我找到了解決辦法。

我把下面的代碼到我的routes.rb

class XHRConstraint 
    def matches?(request) 
    !request.xhr? && !(request.url =~ /\.json$/ && ::Rails.env == 'development') 
    end 
end 

match '(*url)' => 'home#index', :constraints => XHRConstraint.new 

有了這個匹配所有非XHR請求路由到HomeController中返回一個HTML頁面。 XHR請求將由返回JSON響應的其他控制器處理。 另外,我還將以「.json」結尾的請求留在開發環境中進行調試。

+0

偉大的工作人!這應該是upvoted 1000倍。 – wuliwong

+0

適合我! – jordancooperman

+0

我還發現了這個[artsy寫的很棒的文章](http://artsy.github.com/blog/2012/06/25/replacing-hashbang-routes-with-pushstate/),描述瞭如何創建一個全局鏈接處理程序與Backbone pushState以避免頁面刷新,我覺得這是非常與這個答案相結合,可能會幫助一些人。 – jordancooperman

1

這是一個有點棘手的問題,但基本上就是簡單地說,您需要在具有相同(根)頁面的rails中響應所有有效的(HTML)請求,從那裏骨幹將接管並路由到正確的路由處理程序(在你的bakckbone路由器中)。 rails and backbone working together

基本上我做的是創造的每一頁,我想處理和空白觀點行動:

我在這裏更詳細地討論這個問題。我用respond_with返回頁面(這是在每種情況下相同),因爲我處理GET操作爲HTML請求,我在控制器的頂部添加一行:

respond_to :html, :only => [ :show, :new ] 

JSON請求是與respond_with一起處理,但不同於HTML請求實際返回所請求的資源(並且在PUT,POSTDELETE的情況下執行所請求的動作)。

+0

用更多信息更新了我的答案。 –

+0

這將做到這一點,但它不是太優雅的方式,導致所有的骨幹路由必須由Rails負責。所以當你改變客戶端的路由時你必須更新服務器路由。是否真的沒有辦法將所有html請求委託給根控制器? – fey

+1

我不同意:如果您將*全部*請求委派給根控制器,那麼您就是說所有請求都是有效的,而事實上大部分請求都不是。 Rails *需要*知道哪些路由是有效的,哪些不是爲了正確返回不正確路由的狀態碼等。這是重複的,但它是重要的重複。一旦開始使用pushState,這是不可避免的。 –

1

如果您手動完成,主幹將不會被通知您的網址更改。這種改變將被瀏覽器捕獲,並且它將像往常一樣將請求發送到服務器。

同樣,如果您點擊正常的鏈接,它將在沒有通知Backbone的情況下遵循其href

如果您希望Backbone負責URL更改,您必須通過您可用的Backbone工具來完成此操作,並且這是自己的路由器。

所以,如果你想在你必須明確地做它的主幹路的URL變化,是這樣的:

app.router.navigate("my/route", {trigger: true}); 
相關問題