使用Rails的`cycle'来避免视图循环中的`i % 2 == 0'(方法指南)

165 阅读1分钟

有时你需要在渲染一些视图时跟踪你的循环次数,例如交替使用背景颜色来创建一个 "条纹 "表格:

<!-- @foods = ["apple", "orange", "banana"] -->

<% @foods.each do |food| %>
  <tr class="???">
    <td><%= food %></td>
  </tr>
<% end %>

你可以尝试使用:odd:even CSS子选择器,或者切换到each_with_index

<% @foods.each_with_index do |food, i| %>
  <tr class="<%= i % 2 == 0 ? 'bg-gray-200' : 'bg-gray-100' %>">
    <td><%= food %></td>
  </tr>
<% end %>

你甚至可以重构一下,使用i.odd?i.even?

<% @foods.each_with_index do |food, i| %>
  <tr class="<%= i.even? ? 'bg-gray-200' : 'bg-gray-100' %>">
    <td><%= food %></td>
  </tr>
<% end %>

Rails提供了一个不同的辅助工具,在这些情况下很方便:cycle

使用方法

cycle 帮助器需要一个参数数组,每次调用时都会循环浏览这些参数。

我们可以把上面的代码替换成:

<% @foods.each_with_index do |food, i| %>
  <tr class="<%= cycle('bg-gray-200', 'bg-gray-100') %>">
    <td><%= food %></td>
  </tr>
<% end %>

如果你需要两个以上的选项,真正的好处就开始出现了:

<% @foods.each_with_index do |food, i| %>
  <tr class="<%= cycle('bg-red-100', 'bg-orange-100', 'bg-yellow-100') %>">
    <td><%= food %></td>
  </tr>
<% end %>

如果你需要手动重置或在代码之间共享一个cycle ,你可以传递一个name: ,作为一个选项:

cycle("red", "white", "blue", name: "colors")
cycle("sm", "md", "lg", "xl", name: "sizes")

reset_cycle("colors")
reset_cycle("sizes")

你也可以在循环中使用任何对to_s 做出反应的对象:

<% @items.each do |item| %>
  <div class="rotate-<%= cycle(0, 45, 90, 135, 180) %>">
    <%= item %>
  </div>
<% end %>