Почему HAML (в Ruby of Rails) не может необязательно выводить и просто выводить ?

#ruby-on-rails #haml

#ruby-on-rails #haml

Вопрос:

Следующий код предназначен для вывода таблицы из 2 столбцов — для вывода <tr> только каждых 2 элементов; в противном случае, просто <td> , но я обнаружил, что вывод выполняется <tr> постоянно, для каждого <td> , почему это — это ошибка?

 - arr = [2, 4, 6, 8, 10, 12]
%table
  - arr.each_with_index do |num, i|
    - if i % 2 == 0
      %tr
        %td= "column 1: #{num}"
    - else
      %td= "column 2: #{num}"
  

Ответ №1:

Вы также можете использовать each_slice вместо each_with_index . each_slice(2) разбивает исходный массив на 3 группы по 2 массива, чтобы упростить повторение с использованием haml. Код без касания тоже.

 - arr = [2, 4, 6, 8, 10, 12]

%table
  - arr.each_slice(2).each do |row|
    %tr
      %td= "column 1: #{row[0]}"
      %td= "column 2: #{row[1]}"
  

Комментарии:

1. у вас есть хорошее решение, чистое. Я делал 0.upto((arr.length / 2.0).ceil - 1) do |i| ... , что довольно грубо

2. Очень хороший, я еще не знал each_slice . Спасибо 🙂

Ответ №2:

На самом деле, если вы напишете это так:

 - arr = [2, 4, 6, 8, 10, 12]
%table
  - arr.each_with_index do |num, i|
    - if i % 2 == 0
      %tr
        %td= "ODD row #{i}/#{i % 2} - column 1: #{num}"
    - else
      %td= "EVEN row #{i}/#{i % 2} - column 2: #{num}"
  

Вы увидите, что код выполнен правильно. Но HAML автоматически закрывает <TR> тег (закрытие происходит автоматически с отступом).
И аналогично, HAML автоматически добавляет забытый <TR> тег для зависания <TD> .

Итак, один из возможных способов решить эту проблему:

 - arr = [2, 4, 6, 8, 10, 12]
%table
  - arr.each_with_index do |num, i|
    - if i % 2 == 0
      %tr
        %td= "column 1: #{num}"
        %td
          -if arr.size > i 1
            = "column 2: #{arr[i 1]}"
  

Надеюсь, это поможет.

[РЕДАКТИРОВАТЬ: добавлен пример erb]

В erb вы можете сделать это немного приятнее (но я обычно не люблю его использовать):

 <% arr = [2, 4, 6, 8, 10, 12] %>
<table>
  <%= arr.each_with_index do |num, i| %>
    <% if i % 2 == 0 %>
      <tr><td><%= "column 1: #{num}" %></td>
    <% else %>
      <td><%= "column 2: #{num}" %></td></tr>
    <% end %>
  <% end %>
</table>
  

Комментарии:

1. хотя … если делать это таким образом, arr[i 1] не так чисто… это похоже на выполнение некоторого «короткого замыкания» или «взлома» внутри each цикла…

2. Это правильно. Это было просто быстрое предложение, которое работает. Я отредактировал код, чтобы показать пример erb, который работает, но для меня он выглядит ненамного лучше.