【问题标题】:Why do I need `render layout: false` in my Rails controller action?为什么我的 Rails 控制器操作中需要`render layout: false`?
【发布时间】:2017-04-18 00:47:06
【问题描述】:

我正在使用 Working with Javascript 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 返回,尽管请求被正确处理为 Javascript:

Processing by ThingsController#create as JS
  Parameters: {"utf8"=>"✓", "commit"=>"Submit"}
  Rendered things/create.js.erb (0.6ms)

(无论我在控制器操作中是否有明确的respond_to 格式块,问题都是一样的。)

如上所述 herehere,包括控制器操作中的 render layout: false 修复了问题:

# thing_controller.rb
layout 'foo'

def create
  render layout: false
end

但是为什么我在这里需要render layout: false?为什么 Rails 在 html 布局中呈现 javascript?我特别困惑,因为我在其他几个地方使用过相同的成语,以前从未遇到过这个问题。

【问题讨论】:

    标签: javascript ruby-on-rails ruby-on-rails-4


    【解决方案1】:

    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 不寻找任何布局文件来包装您的视图文件(即 rails 引擎只处理 create.js.erb 文件而没有在您的 'foo' 布局上定义 HTML 标头)以将其发送回客户端。

    【讨论】:

      【解决方案2】:

      对于大多数渲染选项,渲染的内容显示为当前布局的一部分。

      您可以使用 :layout 选项告诉 Rails 使用特定文件作为当前操作的布局:

       render layout: false
      

      您听说 Rails 提倡“约定优于配置”。默认渲染就是一个很好的例子。默认情况下,Rails 中的控制器会自动使用与操作对应的名称呈现视图

      您可以使用它来避免特定操作的渲染错误,这可能会影响您的代码延迟

       layout false
       layout 'foo', :except => :create
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-02
        • 1970-01-01
        相关资源
        最近更新 更多