【问题标题】:Rails yield is called multiple times when multiple partials are rendered渲染多个部分时,Rails yield 被多次调用
【发布时间】:2018-08-12 11:47:49
【问题描述】:

我有多个要渲染的部分,我的想法是这些部分连续渲染,并且有不同的内容。所以对于这样的输出:

<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>

如何避免这种情况并返回所需的输出?

【问题讨论】:

    标签: ruby-on-rails view render partial-views yield


    【解决方案1】:

    您完全误解了captures helper 的工作原理。

    每个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 直接流入产量块。

    但是对于这种情况,我想知道您是否不正确地使用它,而一个简单的局部变量可以用更少的hackyness来完成这项工作。

    【讨论】:

      【解决方案2】:

      只需将您的部分替换为刷新提及:

      <!-- 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 %>
      

      【讨论】:

        猜你喜欢
        • 2013-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多