2011-10-03 38 views
2

我對JavaScript比較陌生,雖然我知道是什麼導致了這個錯誤,但我不確定如何重構這個工作。在jQuery「ajax」中關閉工作方法

for (...) { 
    var variableQueryValue = i 

    addLink.bind('click', function() { 
     $.ajax({ 
      type: 'POST', 
      url: '/example', 
      data: 'queryvalue=' + variableQueryValue, 
      success: function(data) { 
       console.log('Got into success method!'); 
      } 
     }); 
    }); 
} 

所以基本上我們綁定一個click事件的一些元素,其數據屬性依賴於一些variableQueryValue改變每次迭代。由於綁定函數處理程序的關閉,在ajax請求中,它將綁定一個事件處理程序,該處理程序爲每次迭代使用相同的variableQueryValue值。

我該如何重構這個,以便將更新的variableQueryValue考慮在內?

感謝您的幫助!

回答

4
function create_handler(j) { 
    return function(e) { 
     $.ajax({ 
      type: 'POST', 
      url: '/example', 
      data: 'queryvalue=' + j, 
      success: function(data) { 
       console.log('Got into success method!'); 
      } 
     }); 
    }; 
} 

for (...) { 
    addLink.bind('click', create_handler(i)); 
} 

調用一個函數來創建您的處理程序,並將i傳遞給該函數。然後讓那個函數返回處理程序被分配到.bind('click',...

這是因爲當你調用一個函數時,你創建一個新的變量環境。因此,當您將i的值傳遞給該函數並在該函數內創建您的處理程序時,您的處理程序現在引用傳遞到該特定變量環境中的值。

處理程序將保留創建它的原始可變環境(即使您要返回處理程序),因此它始終會引用正確的i值。


還有其他解決方案來保留處理程序中使用的持久值的問題,但這可解決特定的關閉問題。根據實際情況,這可能是也可能不是你想要做的。

+0

感謝您的回答。感謝所有回答的人。我會看看,看看哪一個最適合我的情況:) – PolandSpring

+0

這些答案中的很多答案都是一樣的(或者幾乎相同的東西),只是語法不同而已。因此,如何編寫代碼實際上是個人偏好。 –

0

你可以使用.live()來達到這個目的嗎?

的API說:

說明:將一個處理該事件對於當前選擇現在和將來匹配這,所有的元素。

這個我認爲可以解決這個事實,即在您添加事件的時候您的選擇器不存在或者我誤解了?

1

基本上,沒有理由將其綁定到每個鏈接上。選擇組並將事件處理程序綁定到組。

通過在for循環中調用.data(),將所需的任何值添加到addLink。然後在click事件處理程序中檢索值。

0

你可以用每個回調創建封閉:

addLink.bind((function(variableQueryValue) { 
    return function() { 

     // variableQueryValue can be used here 
     $.ajax... 
    }; 
}(variableQueryValue))); 

這樣一來,你會立即運行回調返回一個新的功能至極有一個局部變量保存的,所以它不能從改變外。

1

您需要在for循環的每次迭代過程中關閉一個變量,其值爲i

for (...) { 
    (function(variableQueryValue){ 
     addLink.bind('click', function() { 
      $.ajax({ 
       type: 'POST', 
       url: '/example', 
       data: 'queryvalue=' + variableQueryValue, 
       success: function(data) { 
        console.log('Got into success method!'); 
       } 
      }); 
     }); 
    })(i); 
}