6

我尝试使用 Rails 3.2 和 Backbone.js 使用 pushState 选项制作单页应用程序,但遇到了一些我不理解的问题。

如果我加载应用程序的根 URL (/),一切正常:Rails 返回一个带有 JS 的 HTML 布局,它引导 Backbone,它为 JSON 实体生成一些 XHR 并呈现内容。

但是,如果我从非根 URL开始使用应用程序(例如,通过在浏览器的地址栏中手动键入它),那么 Rails 将尝试使用来自 routes.rb 的路由规则来处理此请求 - 这是错误的,因为它是“主干”路由. 在这种情况下,如何加载页面和引导 Backbone 以处理此 URL?

4

3 回答 3

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”结尾的请求在开发环境中有效以进行调试。

于 2012-08-23T21:25:18.970 回答
1

这是一个有点棘手的问题,但基本上简而言之,您需要使用相同(根)页面响应 rails 中的所有有效(HTML)请求,从那里主干将接管并路由到正确的路由处理程序(在您的bakckbone 路由器)。

我在这里更详细地讨论了这个问题:rails andbone work together

基本上我所做的是为我想要处理的每个页面和空白视图创建操作。我respond_with用来返回页面(在每种情况下都是相同的),并且因为我处理 HTML 请求的 GET 操作,所以我在控制器的顶部添加了这一行:

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

JSON 请求也被处理respond_with,但与 HTML 请求不同,它实际上返回请求的资源(并在PUT,POST和的情况下执行请求的操作DELETE)。

于 2012-08-22T23:19:26.200 回答
1

如果您手动进行,Backbone 将不会被告知您的 url 更改。此更改将被浏览器捕获,并且它将像往常一样将请求发送到服务器。

同样,如果您单击普通链接,它将在href不通知 Backbone 的情况下跟随它。

如果您希望 Backbone 负责更改 url,您必须通过可用的 Backbone 工具来完成,这是自己的路由器。

因此,如果您想以 Backbone 方式更改 URL,您必须明确地进行,例如:

app.router.navigate("my/route", {trigger: true});
于 2012-08-23T11:00:14.273 回答