这一点haml有效:
%select{ :name => 'color', :value => @p.color}
- Person.color.options[:flags].each do |colors|
- if @p.color == colors
%option{:value => colors, :selected => "selected"}= colors
- else
%option{:value => colors}= colors
我试图用它创建一个帮助器,以便我可以重复使用它:
helpers do
def options(prop, p)
Person.prop.options[:flags].each do |x|
if p.prop == x
"%option{:value => #{x}, :selected => 'selected'}= #{x}"
else
"%option{:value => #{x}}= #{x}"
end
end
end
end
然后用:
调用它%select{ :name => 'color', :value => @p.color}
- options(color, @p)
但我收到此错误:undefined local variable or method 'color'
我离得很远吗?
编辑2:
循环中正在发生一些时髦的事情。
即便是一个简单的例子:
helpers do
def options(prop, p)
Person.send(prop).options[:flags].each do |x|
"<p>test</p>"
end
end
end
和= options(:color, @p)
打印一个选项数组(在我的情况下为[:red, :blue, :yellow]
)并且不插入任何html。但是,如果我执行puts <p>test</p>
,它会经历三次循环并正确打印它们 - 它们只是不会显示在HTML中。
答案 0 :(得分:1)
使用符号代替未定义的方法:
options(:color, @p)
而不是:
options(color, @p)
并使用辅助方法使用send
:
if p.send(prop) == x
而不是
if p.prop == x
以及:
Person.send(prop)
而不是:
Person.prop
此外,我有疑问HAML会接受像"%option{:value => #{x}"
这样的字符串作为标记。
您可以使用HTML代替或只是找到另一种干燥方法,例如渲染部分或使用haml_tag
:
def options(prop, p)
Person.send(prop).options[:flags].each do |x|
haml_tag :option, "#{x}", :value=>x
end
end
如果您使用haml_tag
将其与- options(:color, @p)
答案 1 :(得分:1)
这里有几件事情要发生。首先,消息undefined local variable or method 'color'
由行
- options(color, @p)
你在哈姆尔。这里color
是未定义的局部变量。如果我理解正确,你有一个具有各种属性的Person
类,每个类都有几个可能的选项,你希望能够选择使用哪一个而不需要对其进行硬编码并需要多个帮助方法。一种方法是更改行
Person.prop.options[:flags].each do |x|
在你的助手
中Person.send(prop).options[:flags].each do |x|
然后传递一个符号,指定在调用帮助程序时使用的属性:
- options(:color, @p)
下一个问题是将生成的代码写入输出。您的助手可以返回一个可以包含=
的字符串,也可以使用haml_tag
和haml_concat
等助手直接写入输出。请注意,您不应使用haml_tag
或haml_concat
的返回值,否则会产生错误。
所以在这里你可以在帮助器中创建HTML:
if p.prop == x
"<option value='#{x}' selected='selected'>#{x}</option>"
else
"<option value='#{x}' />#{x}</option>"
end
然后将其与=
一起使用(如果使用-
,输出将被忽略):
= options(:color, @p)
如果这样做,您需要确保帮助程序返回要嵌入Haml的字符串。在这种情况下,帮助程序返回调用each
,which is the array itself的值。您需要使用map
和join
之类的内容来创建所需的字符串:
def options(prop, p)
Person.send(prop).options[:flags].map do |x|
if p.prop == x
"<option value='#{x}' selected='selected'>#{x}</option>"
else
"<option value='#{x}' />#{x}</option>"
end
end.join("\n")
end
另一种方法是使用haml_tag
直接写输出。
if p.prop == x
haml_tag :option, x, :value=>x, :selected => true
else
haml_tag :option, x, :value =>x
end
请注意,在Haml中,attribute hash that has a boolean value中的任何条目只会在值为true
时输出,并且会根据输出正确格式化,例如selected='selected'
获得了XHTML,只有selected
用于HTML。所以最后一个例子可以简化为
haml_tag :option, x, :value=>x, :selected => (p.prop == x)
(你总是可以用类似的方式简化另一个例子(返回一个字符串),例如#{"selected='selected'" if p.prop == x}
,但是Haml内置了它。)