Шаблоны: почему мы используем тег <% = для цикла / понимания? - PullRequest
0 голосов
/ 28 ноября 2018

Например:

<table>
  <%= for user <- @users do %>
    <tr>
      <td><b><%= first_name(user) %></b> (<%= user.id %>)</td>
    </tr>
  <% end %>
</table>

Согласно Программированию Phoenix 1.4 (электронная книга, бета):

EEx выполняет код Elixir, который находится внутри тегов <% =%>, внедряярезультат в шаблон.EEx оценивает код в тегах <%%>, не вставляя результат.Мы постараемся по возможности использовать код без побочных эффектов в представлениях, поэтому будем использовать в основном форму <% =%>.

В качестве контрпримера в Rails вы должны написать:

<table>
  <% @users.each do |user| %>

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Сравнение с не имеет смысла, потому что является неизменным, функциональным языком, и по дизайну все в Elixir возвращает что-то , так как выне может изменить состояние.Это включает понимания подобно for, которые возвращают список новых рассчитанных значений.В качестве простого примера посмотрите, что возвращает базовое понимание:

for user <- @users, do: full_name(user)
# => ["John Case", "Mak Ali", "Sarah Middleton"]

Во-вторых, EEx допускает два способа выполнения кода в шаблонах:

  • <% %>, который выполняетоператоры, но отбрасывает результат и
  • <%= %>, который выполняет операторы, а вводит результат в шаблон

Но мы уже используем <%= %> для дочерних элементов в понимании, , поэтому они все еще должны быть внедрены в шаблон, верно?

Нет.На данный момент они все еще находятся внутри блока for, поэтому, даже если вычисляются дочерние элементы с полным именем, они не отображаются, потому что результат самого понимания не включен .

Лучшим сравнением в были бы помощники формы .Если вы не используете <%= > для основного тега form, вся форма не будет обработана, даже если вы используете ее для дочерних тегов.Это связано с тем, что дочерние элементы находятся внутри него и могут отображаться только при отображении самой формы.


Механизм EEx позднее объединяет все элементы списка в шаблон.Вы можете попробовать это сами:

EEx.eval_string("Numbers: <%= list %>", list: ~w[1 2 3])
#=> "Numbers: 123"

EEx.eval_string("Numbers: <%= for i <- list do %> <b><%= i %></b> <% end %>", list: ~w[1 2 3])
#=> "Numbers:  <b>1</b>  <b>2</b>  <b>3</b> "

EEx.eval_string("Numbers: <% for i <- list do %> <b><%= i %></b> <% end %>", list: ~w[1 2 3])
#=> "Numbers: "
0 голосов
/ 28 ноября 2018

Подумайте о том, что делает понимание: оно перебирает список и собирает преобразование каждого входа.Хотя это выглядит как цикл for, на самом деле вы генерируете и собираете серию фрагментов HTML, которые затем объединяются и внедряются в шаблон, когда возвращается понимание.

Если бы это был Ruby,грубый эквивалент может быть:

<%= @users.map {|user| generate_fragment(user) }.join %>

Если вы напишите:

<% @users.map {|user| generate_fragment(user) }.join %>

ваш код будет работать, но он не будет выводить, потому что generate_fragment возвращает строку,вместо прямой отправки в сборщик шаблонов.

Помните, что в функциональных языках вы передаете функцию и оперируете возвращаемым значением этой функции - правильный функциональный код не должен иметь побочных эффектов.Запись в коллектор шаблонов в результате вызова функции будет побочным эффектом!

...