我熟悉使用 Ajax 模板来更新页面的特定部分,但是在执行此操作时如何使用布局进行渲染?例如,给定一个布局:
#foo
= yield :foo
一个简单的 View “show.html.haml”:
= render @bar
和部分:
- content_for :foo
= bar.to_html
... HTML 结果将在布局内呈现,我会看到我的栏内容,但假设我想使用 Ajax 来更新仅 #foo div。我创建“show.js.erb”:
$("#foo").html("<% escape_javascript(render(@bar)) %>");
但结果是什么,因为我的 _bar 部分被渲染但在布局之外,因此我的 :foo 内容永远不会屈服。如何让 JS 模板在该布局内呈现?
最佳答案
我找到了两个答案,但我想知道是否还有更好的方法。 顺便说一句,这些答案是针对 Rails 3 的。
1。使用单独的 JS 布局。
这可能是“更正确”的方法,但不幸的是,它不适用于我的情况,我将很快解释。
我没有完全意识到,在 JS 请求中,查找格式设置为 JS 和 HTML。这意味着如果 JS 模板不存在, Controller 将渲染 HTML 模板。
但它不会以相同的方式查看 HTML 布局,这意味着 HTML 模板将被渲染,但 content_for block 永远不会屈服,从而导致空响应。
因此,为了使上面的简单示例开箱即用。您可以删除“show.js.erb”并在查找路径中添加 JS 布局(例如“bars.js.erb”),如下所示:
$("#foo").html("<% escape_javascript(yield(:foo)) %>");
这样,HTML模板就被渲染出来了,但是在JS布局中,#foo的HTML被换出了响应的新内容。
2。在 JS 响应 block 中渲染 HTML 内容。
但是,#1 这对我来说不是一个理想的答案。我的应用程序使用许多嵌套布局,其中大多数都非常相似。为了使上面的示例工作,我必须创建大量 JS 布局,所有这些布局或多或少都是原始 HTML 布局的副本。浪费时间,而且一点也不干。所以我想出了这个解决方案。
感觉比#1不太理想,请告诉我是否有更合适的方法。但这是我想到的:
# in bars_controller.rb
def show
# ...
respond_to do |format|
format.js do
lookup_context.update_details(:formats => [:html]) do
@content = render_to_string
end
render
end
end
end
这样我就暂时将模板查找的mimetype设置为HTML,将内容渲染到变量中,然后渲染JS模板:
// show.js.erb
$("#foo").html("<%= escape_javascript(@content) %>");
这还有一个更复杂的问题。在我的嵌套布局设置中,在 HTML 响应中,布局调用其父级的渲染来继续构建正文,从而生成完整的页面。就我而言,我希望它只返回正文内容。因此,虽然我不需要此解决方案的 JS 布局,但我确实需要稍微更改我的布局,如下所示:
-# my_layout.html.haml
-# (given a parent layout that yields to :body)
- content_for :body do
= yield(:foo)
- if request.xhr?
= yield(:body)
- else
= render :file => "layouts/my_parent_layout"
通过这种方式,不会在 JS 请求中调用父级,而只是生成主体(到目前为止,在嵌套布局堆栈中)。
关于ruby-on-rails - rails : How do you render with a layout inside a JS template?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3991711/