Rails 渲染多个局部时多次调用 yield
Rails yield is called multiple times when multiple partials are rendered
我有多个正在渲染的部分,我的想法是这些部分连续渲染,并且有不同的内容。所以对于这样的输出:
<div class="container">
<div class="row" data-page='1'>
<h1>Page 1 Title</h1>
</div>
<div class="row" data-page='2'>
<h1>Page 2 Title</h1>
</div>
<div class="row" data-page='3'>
<h1>Page 3 Title</h1>
</div>
</div>
我正在写这样的代码:
<div class="container">
<% (1..3).each do |p| %>
<div class="row" data-page="<%= p %>">
<%= render "partials/o#{p}" %>
<h1><%= yield :title %></h1>
</div>
<% end %>
</div>
<!-- o1 partial -->
<% content_for :title do %>
Page 1 Title
<% end %>
<!-- o2 partial -->
<% content_for :title do %>
Page 2 Title
<% end %>
<!-- o3 partial -->
<% content_for :title do %>
Page 3 Title
<% end %>
上面代码的问题是,在第2页和第3页,它也有前面几页的内容。像这样:
<div class="container">
<div class="row" data-page='1'>
<h1>Page 1 Title</h1>
</div>
<div class="row" data-page='2'>
<h1>Page 1 Title
Page 2 Title</h1>
</div>
<div class="row" data-page='3'>
<h1>Page 1 Title
Page 2 Title
Page 3 Title</h1>
</div>
</div>
我怎样才能避免这种情况并恢复到所需的输出?
只需将您的部分内容替换为齐平提及即可:
<!-- o1 partial -->
<% content_for :title, flush: true do %>
Page 1 Title
<% end %>
<!-- o2 partial -->
<% content_for :title, flush: true do %>
Page 2 Title
<% end %>
<!-- o3 partial -->
<% content_for :title, flush: true do %>
Page 3 Title
<% end %>
您完全误解了 captures helper 的工作原理。
每个 yield
块实质上是在等待整个视图完成渲染,以确保已提供所有内容。您可以将每个命名的 yield 视为一个缓冲区。在您的情况下,即使您多次调用 yield 它们都指向 :title
缓冲区。
content_for
在使用 2+ 个参数调用时将内容写入缓冲区(content_for(:foo, 'bar')
或在使用一个参数调用时输出缓冲区。请注意 content_for
通过设计连接内容:
<%= yield :poem %>
<% content_for :poem, "Roses are red" %>
<% content_for :poem, " violets are blue" %>
# => "Roses are red violets are blue"
这可以通过使用 flush: true
选项来更改,该选项会替换之前捕获的任何内容。
<%= yield :poem %>
<% content_for :poem, "This gets flushed..." %>
<% content_for :poem, "Roses are red violets are blue", flush: true %>
# => "Roses are red violets are blue"
您也可以使用 provide
直接流入 yield 区块。
但对于这种情况,我想知道您是否只是不正确地使用它,一个简单的局部变量就可以完成工作而不那么笨拙。
我有多个正在渲染的部分,我的想法是这些部分连续渲染,并且有不同的内容。所以对于这样的输出:
<div class="container">
<div class="row" data-page='1'>
<h1>Page 1 Title</h1>
</div>
<div class="row" data-page='2'>
<h1>Page 2 Title</h1>
</div>
<div class="row" data-page='3'>
<h1>Page 3 Title</h1>
</div>
</div>
我正在写这样的代码:
<div class="container">
<% (1..3).each do |p| %>
<div class="row" data-page="<%= p %>">
<%= render "partials/o#{p}" %>
<h1><%= yield :title %></h1>
</div>
<% end %>
</div>
<!-- o1 partial -->
<% content_for :title do %>
Page 1 Title
<% end %>
<!-- o2 partial -->
<% content_for :title do %>
Page 2 Title
<% end %>
<!-- o3 partial -->
<% content_for :title do %>
Page 3 Title
<% end %>
上面代码的问题是,在第2页和第3页,它也有前面几页的内容。像这样:
<div class="container">
<div class="row" data-page='1'>
<h1>Page 1 Title</h1>
</div>
<div class="row" data-page='2'>
<h1>Page 1 Title
Page 2 Title</h1>
</div>
<div class="row" data-page='3'>
<h1>Page 1 Title
Page 2 Title
Page 3 Title</h1>
</div>
</div>
我怎样才能避免这种情况并恢复到所需的输出?
只需将您的部分内容替换为齐平提及即可:
<!-- o1 partial -->
<% content_for :title, flush: true do %>
Page 1 Title
<% end %>
<!-- o2 partial -->
<% content_for :title, flush: true do %>
Page 2 Title
<% end %>
<!-- o3 partial -->
<% content_for :title, flush: true do %>
Page 3 Title
<% end %>
您完全误解了 captures helper 的工作原理。
每个 yield
块实质上是在等待整个视图完成渲染,以确保已提供所有内容。您可以将每个命名的 yield 视为一个缓冲区。在您的情况下,即使您多次调用 yield 它们都指向 :title
缓冲区。
content_for
在使用 2+ 个参数调用时将内容写入缓冲区(content_for(:foo, 'bar')
或在使用一个参数调用时输出缓冲区。请注意 content_for
通过设计连接内容:
<%= yield :poem %>
<% content_for :poem, "Roses are red" %>
<% content_for :poem, " violets are blue" %>
# => "Roses are red violets are blue"
这可以通过使用 flush: true
选项来更改,该选项会替换之前捕获的任何内容。
<%= yield :poem %>
<% content_for :poem, "This gets flushed..." %>
<% content_for :poem, "Roses are red violets are blue", flush: true %>
# => "Roses are red violets are blue"
您也可以使用 provide
直接流入 yield 区块。
但对于这种情况,我想知道您是否只是不正确地使用它,一个简单的局部变量就可以完成工作而不那么笨拙。