2016-05-13 33 views
1

我試圖通過對循環變量作爲CoffeeScript的參數傳遞給一個onclick方法如下:的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的循環產生的功能,它的共同插入一個封閉的包裝,以確保循環變量被關閉了,所有生成的函數不要」只是分享最終的價值。 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)