模板:为什么要使用<%=标签进行for循环/理解?

时间:2018-11-27 21:59:20

标签: elixir phoenix-framework

例如:

<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 :(得分:4)

将其与进行比较是没有意义的,因为是一种不变的功能语言,根据设计,Elixir中的所有内容都会返回某物,因为您无法修改状态。其中包括for之类的comprehensions,它们返回计算出的新值的列表。举一个简单的例子,看看基本理解会返回什么:

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

第二,EEx允许通过两种方式在模板中执行代码:

  • <% %>执行语句,但 丢弃结果 ,并且
  • <%= %>执行语句并将 将结果 注入模板

  

但是我们已经在理解中使用了<%= %>作为子元素,所以仍然应该将它们注入模板中,对吧?

不。此时,它们仍位于for块中,因此即使计算了全名的子元素,也不会呈现它们,因为不包括理解本身的结果

中更好的比较是form helpers。如果您没有将<%= >用于主要的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: "

答案 1 :(得分:1)

考虑一个理解的作用:它遍历一个列表,并收集每个输入的转换。尽管它看起来像一个for循环,但是您真正要做的是生成并收集一系列HTML片段,一旦理解返回,所有这些片段就会合并并注入模板中。

如果是Ruby,则大致等同于:

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

如果您要写:

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

您的代码可以运行,但不会产生任何输出,因为generate_fragment返回一个字符串,而不是直接发送给模板收集器。

请记住,在函数式语言中,您向函数提供输入并对该函数的返回值进行操作-正确的函数代码应该没有副作用。由于函数调用而写入模板收集器会产生副作用!