我尝试使用带有pushState选项的Rails 3.2和Backbone.js构建单页应用程序,但遇到了一些我不理解的东西。
如果我加载应用程序的根URL(/),一切顺利:Rails返回一个带有JS的HTML布局,它引导Backbone,它为JSON实体制作一些XHR并呈现内容。
但是,如果我从非根URL 开始使用应用程序(例如,通过在浏览器的地址栏中手动输入),那么Rails将尝试使用来自routes.rb的路由规则来处理此请求 - 这是错误的,因为它是一个“骨干”的路线。在这种情况下,如何加载页面并引导Backbone以处理此URL?
答案 0 :(得分: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请求都将路由到返回HTML页面的HomeController。并且XHR请求将由返回JSON响应的其他控制器处理。 另外,我将以“.json”结尾的请求留在开发环境中用于调试。
答案 1 :(得分:1)
这是一个有点棘手的问题,但基本上简而言之,您需要响应具有相同(根)页面的rails中的所有有效(HTML)请求,从那里骨干将接管并路由到正确的路由处理程序(在您的bakckbone路由器中)。
我在这里更详细地讨论了这个问题:rails and backbone working together
基本上我所做的是为我想要处理的每个页面和空白视图创建操作。我使用respond_with
返回页面(在每种情况下都是相同的),因为我处理HTML请求的GET操作 ,我在控制器的顶部添加了这一行: / p>
respond_to :html, :only => [ :show, :new ]
JSON请求也使用respond_with
处理,但与HTML请求不同的是,实际返回请求的资源(并在PUT
,POST
和{{的情况下执行请求的操作1}})。
答案 2 :(得分:1)
Backbone将不会通知您的网址更改。此更改将被浏览器捕获,它将按照惯例将请求发送到服务器。
如果您点击普通的链接,它会跟随href
,而不通知Backbone。
如果您希望Backbone负责更改网址,您必须通过您可用的Backbone工具执行此操作,这是自己的路由器。
因此,如果您想以Backbone的方式更改URL,则必须明确地执行此操作,例如:
app.router.navigate("my/route", {trigger: true});