传递参数以在Rails 3中产生(或者可能吗?)

时间:2012-05-25 09:17:27

标签: ruby-on-rails-3 erb yield content-for

我正在尝试使用yieldcontent_for创建动态内容。基本上我有一堆布局。我不想为每个布局创建一堆视图。我想在需要时渲染视图部件。对于代码的不同部分,它是可以的。但我对不同内容的相同部分存在问题。

application.html.erb

<%= yield %>
<%= yield :name_section %>

在我的show.html.erb我有;

<% content_for :name_section do %>
    <b>Name:</b>
    <%= @post.name %>
<% end %>

这是问题;

如果我想要使用不同内容的多个name_section,该怎么办?我的意思是;我希望在我的视图中将:name_section个不同的位置放在不同的内容中。

对于前任;

<table>
  <tr>
    <td>
      <%= yield :name_section %>
    </td>
  </tr>
  <tr>
    <td>
      <%= yield :name_section %>
    </td>
  </tr>
</table>

有什么想法吗?

谢谢。 Çağdaş

3 个答案:

答案 0 :(得分:6)

我相信你现在要求的是:

# The template
<%= render layout: "my_layout" do |customer| %>
  Hello <%= customer.name %>
<% end %>

# The layout
<html>
  <%= yield Struct.new(:name).new("David") %>
</html>

自: http://api.rubyonrails.org/classes/ActionView/Helpers/RenderingHelper.html#method-i-_layout_for

希望这可以帮助其他人寻找相同的解决方案。

答案 1 :(得分:2)

鉴于文件:

http://api.rubyonrails.org/classes/ActionView/Helpers/RenderingHelper.html#method-i-_layout_for

和方法的源代码(你可以在那里浏览):

def _layout_for(*args, &block)
  name = args.first

  if block && !name.is_a?(Symbol)
    capture(*args, &block)
  else
    super
  end
end

布局中yield无法满足您的要求。

答案 2 :(得分:2)

以下解决方案对我来说很有效。它不允许您传递args,但如果在调用content_for之前(第二次),则将args分配给实例变量,这允许您在content_for中引用实例变量。基本思想是content_for在第一次调用内容时生成内容,然后内容保持静态,但这种解决方法会延迟静态内容生成,直到您准备好显示内容为止。

首先,将此函数添加到助手模块:

def immediate_content_for name, content = nil, &block
  @immediate_content ||= {}
  if content || block_given? then
    @immediate_content[name] = Proc.new { content_for name, content, &block }
    nil
  else
    @immediate_content[name].call
    content_for name
  end
end

然后,假设您要将arg1传递给content_for。你现在可以这样做:

<% content_for :my_form %>
  <%= some_helper_function(@arg1) %>
<% end %>

然后,在您的代码中稍后,在您定义的arg1之后:

<%= @arg1 = arg1 %>
<%= content_for :my_form %>

从某种意义上说,我无法保证immediate_content_for的行为与content_for的行为完全相同,并且content_for的行为发生了变化在某些未来版本的rails中,如果您希望它继续镜像immediate_content_for,则需要更新content_for。虽然它不是最佳解决方案,但它现在可以胜任。