为什么我的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