2016-05-13 2 views
1

Я пытаюсь передать для переменного цикла в качестве аргумента метода OnClick в CoffeeScript следующим образом:CoffeeScript - Как применять закрытие и анонимные функции

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. Но как это исправить в кофе?

ответ

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 для создания функции, это общие для вставки закрывающих оберток для того, чтобы гарантировать, что петли переменных накрыли, и все сгенерированные функции Дона» t просто разделяйте конечные значения. 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 
+0

он не работает. приводит к ошибке 'this.selectThis' не является функцией – vipin8169

+1

Это потому, что цикл должен быть' do (index, option_value) => '(для сохранения' @ 'внутри SIF), а не' do (index, option_value) -> '. –

+0

Спасибо за помощь. Но в чем разница между -> и => в кофе? – vipin8169

1

Наконец нашел правильный синтаксис, вздыхают:

onClick: @selectThis.bind(null, option_value)