2013-01-31 36 views
2

我寫了一些JavaScript來運行一組「模塊」。對於每個模塊,它會調用ajax,獲取模塊的html,並將模塊轉儲到頁面佈局上的兩列之一。如何在ajax回調中保留一個變量?

var modules = [ 
    { name: 'ExchangeStatus', title: 'Exchange Status', column: 'left' }, 
    { name: 'Grid', title: 'Contacts', column: 'right' } 
    { name: 'Filters', title: 'Filters', column: 'left' } 
], 
modulesUrl = '/Modules/'; 

for (var count = 0; count < modules.length; count++) { 
    var module = modules[count]; 

    // Get module HTML. 
    $.ajax({ 
     url: modulesUrl + module.name, 
     success: function (moduleHtml) { 

      // Append module HTML to appropriate element. 
      $('#' + module.column + 'Column').append(moduleHtml); 

      // Custom event to trigger the module to load its data. 
      var initializeModuleEvent = $.Event('initialize' + module.name); 
      initializeModuleEvent.firstLoad = true; 
      $(document).trigger(initializeModuleEvent); 

     } 
    }); 
} 

問題在於for循環創建競爭條件。在ajax回調中,module.column幾乎總是最後一個模塊的值,因爲for循環在ajax回調返回之前很久才完成。我如何維護模塊變量,以便每個回調都處理相應的模塊?目前,所有三個模塊都在左列中結束,因爲循環中的最後一個模塊位於左列。

+0

可能重複[關閉的Javascript內循環 - 簡單實用的例子(HTTP://計算器。 com/questions/750486/javascript-closure-inside-loops-simple-practical-example) –

回答

7

你可以嘗試創建一個額外的範圍,通過module

for (var count = 0; count < modules.length; count++) { 
    var module = modules[count]; 

    (function(module) { 
     $.ajax({ 
     ... 
     }) 
    }(module)); 

編輯:如果你願意,你可以使用forEach還有:

modules.forEach(function(module) { 
// 'module' will be available everywhere in this scope 
}); 
+0

非常感謝!我覺得愚蠢的是沒有考慮自己使用閉包,但我真的很感激它:D – Chev

+0

這不是唯一的選擇,但最明顯的。如果你願意,你可以使用'forEach'並忘記關閉。 – elclanrs

+0

我沒有意識到JavaScript有一個'forEach' ...我似乎無法得到它的工作。編輯:哦,陣列本身的功能。尼斯。 – Chev

1

這將有助於

for (var count = 0; count < modules.length; count++) { 
    var module = modules[count]; 

    (function (module) { 
     // Get module HTML. 
     $.ajax({ 
      url: modulesUrl + module.name, 
      success: function (moduleHtml) { 

       // Append module HTML to appropriate element. 
       $('#' + module.column + 'Column').append(moduleHtml); 

       // Custom event to trigger the module to load its data. 
       var initia`enter code here`lizeModuleEvent = $.Event('initialize' + module.name); 
       initializeModuleEvent.firstLoad = true; 
       $(document).trigger(initializeModuleEvent); 

      } 
     }); 
    })(module) 
} 
2

修改您的成功callb確認此:

$.ajax({ 
    url: modulesUrl + module.name, 
    success: (function (module) { 
     return function (moduleHtml) { 
      // Append module HTML to appropriate element. 
      $('#' + module.column + 'Column').append(moduleHtml); 

      // Custom event to trigger the module to load its data. 
      var initializeModuleEvent = $.Event('initialize' + module.name); 
      initializeModuleEvent.firstLoad = true; 
      $(document).trigger(initializeModuleEvent); 
     }; 
    }(module)); 
}); 

這將創建一個新的範圍爲適當module變量的值。

有沒有必要包裝整個ajax電話在這裏。

+0

哦,我覺得這看起來有點乾淨。 – Chev

0

試試這種方式,告訴我它是否有效!

for (var n = 0; n < modules.length; n++) { 
(function() { 
    var i = n; 
     var module = modules[i]; 

     // Get module HTML. 
     $.ajax({ 
      url: modulesUrl + module.name, 
      success: function (moduleHtml) { 

       // Append module HTML to appropriate element. 
       $('#' + module.column + 'Column').append(moduleHtml); 

       // Custom event to trigger the module to load its data. 
       var initializeModuleEvent = $.Event('initialize' + module.name); 
       initializeModuleEvent.firstLoad = true; 
       $(document).trigger(initializeModuleEvent); 

      } 
     }); 
    }()); 
} 
2

而不是使用for循環使用jQuery的每..這將解決這個問題的

var modules = [ 
    { name: 'ExchangeStatus', title: 'Exchange Status', column: 'left' }, 
    { name: 'Grid', title: 'Contacts', column: 'right' } 
    { name: 'Filters', title: 'Filters', column: 'left' } 
], 
modulesUrl = '/Modules/'; 

$(modules).each(function(index, elem) 
{ 
    var module = elem; 

    // Get module HTML. 
    $.ajax({ 
     url: modulesUrl + module.name, 
     success: function (moduleHtml) { 

      // Append module HTML to appropriate element. 
      $('#' + module.column + 'Column').append(moduleHtml); 

      // Custom event to trigger the module to load its data. 
      var initializeModuleEvent = $.Event('initialize' + module.name); 
      initializeModuleEvent.firstLoad = true; 
      $(document).trigger(initializeModuleEvent); 

     } 
    }); 
} 
} 
); 
+0

我過去遇到的唯一問題是jQuery的'each'也會迭代對象的屬性。我曾經在服務器返回錯誤的地方出現了一個令人討厭的錯誤,jQuery凍結了嘗試迭代不應該重複的頁面。因爲它,我現在可能是偏執狂了,哈哈。 – Chev

相關問題