【问题标题】:Yield and default case || do not output default case收益率和默认情况 ||不输出默认大小写
【发布时间】:2011-02-23 20:02:37
【问题描述】:

我有一个简单的 yield 用例,由于某种未知原因,默认情况从未显示:

在我的 super_admin 布局中,我有:

<%= yield :body_id || 'super_admin_main' %>

我的控制器

class Superadmin::GolfsController < ApplicationController
  layout "super_admin"

  def show 

  end
end

我的节目视图

有或没有

<% content_for(:body_id) do %>sadmin_golfs<% end %>

使用:显示 sadmin_golfs。

without显示空字符串而不是 super_admin_main

任何人都可以重现相同的行为吗?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 view


    【解决方案1】:

    试试&lt;%= yield(:title).presence || 'My Default Title' %&gt;

    Object#presence 等同于object.present? ? object : nil(AS 3 rc 文档),并且基本上允许带有标题的传统语法。

    【讨论】:

    • 这是 rails 3 的更好答案
    【解决方案2】:

    使用括号:

    <%= (yield :body_id) || 'super_admin_main' %>
    

    或者

    <%= yield(:body_id) || 'super_admin_main' %>
    

    如果没有它们,则假设 yield (:body_id || 'super_admin_main')

    编辑:Rails 3 使用 ActiveSupport::SafeBuffer 而不是 string/nil (Rails 2),因此即使没有提供 content_for,输出也不是 nil。所以试试:

    <%= yield(:body_id).empty? ? 'super_admin_main' : yield(:body_id)%>
    

    【讨论】:

    • 实际上,当没有提供 content_for 时,它仍然显示一个空字符串。
    • 您根本不提供content_for 或者它只是像&lt;% content_for(:body_id) do %&gt; &lt;% end %&gt; 一样的空白?
    • 尝试渲染部分内容如何?寻找在特定视图中覆盖侧边栏的能力:&lt;%= yield(:sidebar).empty? ? 'special_sidebar' : yield(:sidebar) %&gt;
    • 错过了.presence --> yield(:body_id).presence
    【解决方案3】:

    为什么不测试是否有 content_for 或没有在视图编译中定义。

    在 content_for 代码中我们可以看到:

    def content_for(name, content = nil, &block)
      ivar = "@content_for_#{name}"
      content = capture(&block) if block_given?
      instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{content}".html_safe)
      nil
    end
    

    因此,在您的情况下,@content_for_body_id 定义了 content_for 是否在您的视图中。

    你可以制作:

    <%=  instance_variable_defined?('@content_for_body_id') ? yield(:body_id) : 'super_admin_main' %>
    

    如果你愿意,你可以在之后生成一个帮助器

    def yield_or(part, result)
      instance_variable_defined?("@content_for_#{part}") ? instance_variable_get("@content_for_#{part}") : result
    end
    

    并在你的视图中调用它

    <%= yield_or(:body_id, 'super_admin_main') %>
    

    它仅适用于 Rails 2.3.x

    在 Rails 3 中:

    有这个方法content_for?

    【讨论】:

      【解决方案4】:

      在 Rails 3 中

      引发未定义的方法`present'

      【讨论】:

      • 迄今为止我发现的最优雅的解决方案(没有宝石)。谢谢。
      【解决方案5】:

      我知道这是一个老问题,但我有 Rails 2.3 的解决方案。

      我已经扩展了上面的 shingara's yield_or 辅助方法,所以它现在可以接受一个块:

      module ApplicationHelper
        def yield_or(name, content = nil, &block)
          ivar = "@content_for_#{name}"
      
          if instance_variable_defined?(ivar)
            content = instance_variable_get(ivar)
          else
            content = block_given? ? capture(&block) : content
          end
      
          block_given? ? concat(content) : content
        end
      end
      

      这可以在你的模板中使用:

      <% yield_or :something do %>
          <p>something else</p>
      <% end %>
      

      <%= yield_or :something, 'something else' %>
      

      【讨论】:

        【解决方案6】:
        <div class= <%= (yield :content_with_bunners).present? ? yield(:content_with_bunners) : "col-md-10"%>>
        

        【讨论】:

          【解决方案7】:

          你可以使用content_for?(:body_id),代码会这样。

          <%= content_for?(:body_id) ? yield(:body_id) : 'super_admin_main' %>
          

          【讨论】:

            猜你喜欢
            • 2019-05-22
            • 1970-01-01
            • 2015-08-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-02-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多