1

次のように、for ループ変数を引数として coffeescript の onclick メソッドに渡そうとしています。

for index, option_value of @state.option_values
                  dom.span
                    key: "#{index} #{option_value.name}"
                    className: "pull-left col-md-3#{if option_value.selected then ' selected' else ''}"
                    onClick: () => @selectThis option_value


selectThis: (option_value_selected) ->
    alert(option_value_selected.name)

ただし、option_value常に in の最後の値を参照しoption_valueます@state.option_values。これをプレーンなJavaScriptで修正する方法を知っています。しかし、コーヒーでこれを修正する方法は?

4

2 に答える 2

2

問題は、あなたの機能です:

onClick: () => @selectThis option_value

is は、option_value後でonClickハンドラーが呼び出されるまで評価されない参照を格納するだけです。

これは、JavaScript と CoffeeScript のループでよくある問題であり、解決策は常に同じです。無名関数が作成されたときに、変数を強制的に評価することです。君の:

@selectThis.bind(null, option_value)

関数を呼び出すことでそれを行いFunction.prototype.bindます(ただし、関数が呼び出されたときに@なるnullので注意してください)。

JavaScript の一般的なイディオムは、ループ本体を自己呼び出し関数に変えることです。

for(i = 0; i < 6; ++i)
    (function(i) { ... })(i)

繰り返しごとにループ変数を強制的に評価します。CoffeeScript には、このイディオムのショートカットとしてdoループがあります。

JavaScript ループを使用して関数を生成する場合、ループ変数が確実に閉じられるようにするためにクロージャー ラッパーを挿入するのが一般的であり、生成されたすべての関数が最終的な値を共有するだけではありません。CoffeeScript はdoキーワードを提供します。このキーワードは、渡された関数をすぐに呼び出し、引数を転送します。

慣用的な CoffeeScript ソリューションは次のようになります。

for index, option_value of @state.option_values
  do (index, option_value) =>
    dom.span
      key: "#{index} #{option_value.name}"
      className: "pull-left col-md-3#{if option_value.selected then ' selected' else ''}"
      onClick: => @selectThis option_value
于 2016-05-13T17:12:50.693 に答える
1

最後に正しい構文を見つけました。

onClick: @selectThis.bind(null, option_value)
于 2016-05-13T15:57:12.383 に答える