例如:
<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| %>
答案 0 :(得分:4)
将其与ruby进行比较是没有意义的,因为elixir是一种不变的功能语言,根据设计,Elixir中的所有内容都会返回某物,因为您无法修改状态。其中包括for
之类的comprehensions,它们返回计算出的新值的列表。举一个简单的例子,看看基本理解会返回什么:
for user <- @users, do: full_name(user)
# => ["John Case", "Mak Ali", "Sarah Middleton"]
第二,EEx
允许通过两种方式在模板中执行代码:
<% %>
执行语句,但 丢弃结果 ,并且<%= %>
执行语句并将 将结果 注入模板但是我们已经在理解中使用了
<%= %>
作为子元素,所以仍然应该将它们注入模板中,对吧?
不。此时,它们仍位于for
块中,因此即使计算了全名的子元素,也不会呈现它们,因为不包括理解本身的结果。
在rails中更好的比较是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
返回一个字符串,而不是直接发送给模板收集器。
请记住,在函数式语言中,您向函数提供输入并对该函数的返回值进行操作-正确的函数代码应该没有副作用。由于函数调用而写入模板收集器会产生副作用!