为什么我的Rails控制器操作中需要`render layout:false`?
我使用remote: true
来自使用Jails in Rails指南的remote: true
成语:
# new.html.slim = form_for @thing, remote: true do |f| f.text_field :whatever f.submit 'Submit'
# thing_controller.rb layout 'foo' def create end
# create.js.erb alert('foobar')
这失败了,因为create.js.erb
由于某种原因在’foo’布局中呈现并以html而不是javascript的forms返回,尽管请求被正确处理为Javascript:
Processing by ThingsController#create as JS Parameters: {"utf8"=>"✓", "commit"=>"Submit"} Rendered things/create.js.erb (0.6ms)
(无论我是否在控制器操作中有明确的respond_to
格式块,问题都是一样的。)
如此处和此处所述 ,在控制器操作中包括render layout: false
可修复问题:
# thing_controller.rb layout 'foo' def create render layout: false end
但为什么我需要render layout: false
这里是render layout: false
? 为什么Rails在html布局中呈现javascript? 我特别困惑,因为我在其他几个地方使用过相同的成语,从来没有遇到过这个问题。
rails中的操作控制器默认响应HTML响应(除非另有说明)。
layout 'foo'
强制使用app/views/layouts/foo.html.slim
作为视图文件的模板。 所以与你的thing_controller.rb
上的动作相关的所有视图都在布局’foo’中呈现,并且使用布局’foo’生成的最终HTML和视图文件create.html.slim
默认发送回客户端。
如果要强制返回js模板而不是HTML文件,则需要在操作中明确定义它,如下所示:
# thing_controller.rb layout 'foo' def create respond_to do |format| # use :template if your view file is somewhere else than rails convention format.js { :template => "somewhere/create.js.erb", :layout => false } end end
其中render layout: false
强制执行rails NOT TO寻找任何布局文件来包装你的视图文件(即rails引擎只处理你的’foo’布局中没有定义HTML头的create.js.erb
文件),然后将其发送回客户端。
对于要渲染的大多数选项,渲染的内容将显示为当前布局的一部分。
您可以使用:layout选项告诉Rails使用特定文件作为当前操作的布局:
render layout: false
您已经听说过Rails提升了“约定优于配置”。默认渲染就是一个很好的例子。 默认情况下,Rails中的控制器自动呈现具有与操作对应的名称的视图
您可以使用它来避免特定操作的呈现为false,这可能会影响您的代码延迟
layout false layout 'foo', :except => :create