使用“ìn”访问关键字列表的意外行为

时间:2016-06-15 09:17:16

标签: phoenix-framework

在我的模板(html.eex文件)中,我正在尝试使用关键字列表来传递选项。我有:

<%= if :layer1 in @buttonCSS do %><%= @buttonCSS[:layer1] %><% end %>

然后,我传递这样的值,我使用我的模板:

<%= render MyProject.ComponentView, "button.html",
    buttonCSS: [layer1: "font-style: italic;"]
%>

如果我不使用if条件,则可行。 那么,in不应该在这里工作吗?

我尝试使用layer1代替:layer1,但后来发生错误。

PS:另外,为什么使用.layer1代替[:layer1]不起作用?

2 个答案:

答案 0 :(得分:2)

在查找可枚举元素时使用

in/2(在引擎盖下使用Enum.member?/2)。

iex> :foo in [:foo]  
true
iex> :foo in [foo: :bar]
false

这将有效,因为如果未设置@buttonCSS[:layer1],它将返回nil。

<%= @buttonCSS[:layer1] %>

答案 1 :(得分:2)

由于关键字列表只是列表,in实际上会检查列表中是否存在整个键/值对:

iex(1)> :a in [a: 1]
false
iex(2)> {:a, 1} in [a: 1]
true

您应该检查@buttonCSS[:layer1]是否真实,因为不存在的密钥会返回nil,这是假的:

<%= if @buttonCSS[:layer1] do %>
  <%= @buttonCSS[:layer1] %>
<% end %>

如果您实际上只是在if内打印了该值,则可以跳过if并直接打印该值,因为打印nil不会打印任何内容:

<%= @buttonCSS[:layer1] %>

演示:

iex(1)> EEx.eval_string "<%= @buttonCSS[:layer1] %>", assigns: [buttonCSS: [layer1: "foo"]]
"foo"
iex(2)> EEx.eval_string "<%= @buttonCSS[:layer1] %>", assigns: [buttonCSS: []]
""
  

PS:另外,为什么使用.layer1代替[:layer1]不起作用?

点语法仅适用于地图(以及模块中的功能),不适用于关键字列表。它应该有效:如果你有:

buttonCSS: %{layer1: "font-style: italic;"}

但请注意,点语法与[]不同:如果某个键不存在而不是返回nil,则会引发错误。