2012-10-10 34 views
0

可能重複:
Javascript Closure Problem將函數句柄放入jquery點擊事件函數的範圍問題?

在下面的代碼,TrueThis.aChoices[i]['CallBack']是當創建click事件和 「假」 時,單擊事件實際發生的功能。如何獲取click事件處理程序的函數引用?

我的對象:

ATK.MultiChoiceDialog = function() { 

    var TrueThis = this; 
    var aChoices; 

    this.Show = function(sTitle,sPrompt,aChoices){ 
     this.aChoices = aChoices; 

     var HTML = '[snip]'; 
     $('body').append(HTML); 

     for(var i in this.aChoices) 
     {  
     console.log(TrueThis.aChoices[i]['CallBack']); // shows "function" 
     $('#ATKDialogButton'+i).click(function(e){ 
      console.log(TrueThis.aChoices[i]['CallBack']); // shows "false" ??? 
      if(TrueThis.aChoices[i]['CallBack']) 
      { 
       TrueThis.aChoices[i]['CallBack'].call(aChoices[i]['Context']); 
      } 
     });  
     } 
    } 
}; 

我也試過這樣:

for(var i in this.aChoices) 
{  
    var CB = TrueThis.aChoices[i]['CallBack']; 
    console.log(CB); // function 
    $('#ATKDialogButton'+i).click(function(e){ 
     console.log(CB); // false 
     if(TrueThis.aChoices[i]['CallBack']) 
     { 
     TrueThis.aChoices[i]['CallBack'].call(aChoices[i]['Context']); 
     } 
    });  
} 
+2

我正在遞增到i的最後一個值,所以對於所有點擊事件,我將是最後一個迭代的項目,而不是事件綁定時的最後一個項目。 –

+0

如果您需要在循環中的處理程序的回調函數中使用循環變量的值,則應該將該綁定封裝在發送該變量的閉包中,或者創建一個將該變量作爲參數並調用的單獨函數循環中的函數 – MrOBrian

+0

@ruakh搜索「臭名昭着的循環問題」 –

回答

1

jQuery有由事件數據傳遞給回調函數處理這一個內置的方式被綁定到事件。

ATK.MultiChoiceDialog = function() { 

    var TrueThis = this; 
    var aChoices; 

    this.Show = function(sTitle,sPrompt,aChoices){ 
     this.aChoices = aChoices; 

     var HTML = '[snip]'; 
     $('body').append(HTML); 

     for(var i in this.aChoices){ // in js the '{' should be on same line 
     console.log(TrueThis.aChoices[i]['CallBack']); // shows "function" 
      $('#ATKDialogButton'+i).click({i:i},function(e){ // data passed in with {i:i} 
      console.log(TrueThis.aChoices[e.data.i]['CallBack']); // shows "function" 
      if(TrueThis.aChoices[e.data.i]['CallBack']){ // in js the '{' should be on same line 
       TrueThis.aChoices[e.data.i]['CallBack'].call(aChoices[e.data.i]['Context']); 
      } 
     });  
     } 
    } 
};​ 
+0

+1我不知道'click'函數可以做到這一點。 – Nick

+0

afaik所有jQuery事件綁定方法現在都具有此功能。 –

0

感謝評論,我有這個工作。首先創建一個新函數來「修復」我的值,它返回事件處理函數的函數。

this.FixI = function (i){ 
    return function(e){ 
     if(TrueThis.aChoices[i]['CallBack']) 
     { 
     TrueThis.aChoices[i]['CallBack'].call(TrueThis.aChoices[i]['Context']); 
     } 
    } 
} 

使用新的函數生成,甚至處理器的循環功能:

for(var i in this.aChoices) 
{ 
    $('#ATKDialogButton'+i).click(TrueThis.FixI(i));  
} 

UPDATE:它看起來像凱文乙發現解決,不需要這個問題的一個jQuery的方式一個額外的「保存者」功能。