2

这一点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 中。

4

2 回答 2

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 代替,或者只是找到另一种 DRY 方式,例如渲染部分或使用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)

于 2012-12-01T04:15:34.103 回答
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)

下一个问题是将生成的代码写入输出。您的助手可以返回一个可以包含在内的字符串,也可以使用和=等助手直接写入输出。请注意,您不应该使用or的返回值,它会产生错误。haml_taghaml_concathaml_taghaml_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即数组本身。您需要使用类似的东西mapjoin创建所需的字符串:

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 中,属性散列中具有布尔值的任何条目只有在值为时才会输出true,并且它将根据输出正确格式化,例如获取selected='selected'XHTML 并且仅selected用于 HTML。所以最后一个例子可以简化为

haml_tag :option, x, :value=>x, :selected => (p.prop == x)

(你总是可以用类似的方式简化另一个例子(返回一个字符串),比如#{"selected='selected'" if p.prop == x},但 Haml 已经内置了它。)

于 2012-12-01T08:45:08.997 回答