我试图将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
始终引用option_value
中@state.option_values
的最后一个值。我知道如何在普通的JavaScript中解决这个问题。但是,如何在咖啡中解决这个问题?
答案 0 :(得分:2)
问题在于你的功能:
onClick: () => @selectThis option_value
只是存储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
loops作为这个习语的捷径:
当使用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
答案 1 :(得分:1)
终于找到了正确的语法,感叹:
onClick: @selectThis.bind(null, option_value)