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>と、ループが3回実行され、正しく出力されます。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さまざまなプロパティを持つクラスがあり、それぞれにいくつかの可能なオプションがあり、ハードコーディングせずに使用するものを選択し、いくつかのヘルパー メソッドを必要としないようにしたいと考えています。それを行う1つの方法は、行を変更することです

Person.prop.options[:flags].each do |x|

あなたのヘルパーで

Person.send(prop).options[:flags].each do |x|

次に、ヘルパーを呼び出すときに使用するプロパティを指定するシンボルを渡します。

- options(:color, @p)

次の問題は、生成されたコードを出力に書き込むことです。ヘルパーは、 に含めることができる文字列を返すか、や=などのヘルパーを使用して出力に直接書き込むことができます。またはの戻り値を使用しないでください。エラーが発生します。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 に答える