我正在尝试使用yield
和content_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ş
答案 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
。虽然它不是最佳解决方案,但它现在可以胜任。