Iterating à travers un tableau tout en effectuant une demande pour chaque entrée

Voici mon problème. J'ai un tableau contenant le nom des villes dont j'ai besoin pour rechercher la météo. Donc, je bouge dans chaque ville et effectue une requête AJAX pour récupérer la météo.

var LOCATION = 'http://www.google.com/ig/api?weather='; $( document ).ready( function() { for( var cityIdx = 0; cityIdx < cities.length; cityIdx++ ) { $.ajax({ type: 'GET', url: LOCATION + cities[ cityIdx ], dataType: 'xml', success: function( xml ) { if( $( xml ).find( 'problem_cause' ) != 0 ) { // Do what I want with the data returned var weather = $( xml ).find( 'temp_c' ).attr( 'data' ); } } }); } }); 

Le problème que je rencontre est que dans la fonction de succès, je ne peux pas accéder au nom de la ville (via les villes [cityIdx]). J'ai inséré une alerte () dans la boucle for et la fonction de succès et il semble que la boucle soit exécutée city.length fois, puis j'obtiens les alertes de fonction de succès. Mon objectif est de faire boucle dans chaque ville pour obtenir la météo et la montrer sur ma page avec le nom de la ville associée.

De plus, qu'est-ce que vous suggérez que je devrais faire pour séparer le contenu et la présentation?

Je vous remercie. 🙂

Je soupçonne que votre problème est similaire à l'exemple de http://ejohn.org/apps/learn/ . La variable d'index cityIdx est mise à jour dans la fermeture que vous créez au fur et à mesure que la boucle for est traitée, de sorte qu'au moment de l'exécution de votre fonction, cityIdx indiquera le dernier élément du tableau. La solution consiste à utiliser une fonction anonyme évaluée pour créer un contexte indépendant, où la valeur de l'indice n'est pas mise à jour.

 //... success: (function(cities, idx) { return function( xml ) { if( $( xml ).find( 'problem_cause' ) != 0 ) { // Do what I want with the data returned // use cities[idx] var weather = $( xml ).find( 'temp_c' ).attr( 'data' ); } }; })(cities, cityIdx) //... 

Étant donné que Javascript utilise les fonctions de fermeture, j'ai trouvé que le moyen le plus simple pour moi était d'envelopper simplement le contenu de la boucle for dans une fonction en ligne qui copie le nom actuel de la ville vers une variable à laquelle elle aura toujours accès.

 $(document).ready(function() { for (var cityIdx = 0; cityIdx < cities.length; cityIdx++) { new function() { var currentCity = cities[cityIdx]; $.ajax({ type: 'GET', url: LOCATION + currentCity, dataType: 'xml', success: function(xml) { alert(currentCity); if ($(xml).find('problem_cause') != 0) { // Do what I want with the data returned var weather = $(xml).find('temp_c').attr('data'); } } }); }(); // the "();" calls the function we just created inline } }); 

Pourquoi ne pas utiliser jQuery pour itérer dans votre tableau? Utilisez jQuery chaque fonction:

  var LOCATION = 'http://www.google.com/ig/api?weather='; $( document ).ready( function() { $.each(cities, function() { //assign the current city name to a variable var city = this; $.ajax({ type: 'GET', url: LOCATION + city, dataType: 'xml', success: function( xml ) { if( $( xml ).find( 'problem_cause' ) != 0 ) { alert(city); // Do what I want with the data returned var weather = $( xml ).find( 'temp_c' ).attr( 'data' ); } } }); }); }); 

L'alerte dans la fonction de succès affiche la ville correcte.

La chose la plus simple à faire serait que votre demande AJAX renvoie le nom de la ville.

Pour diverses raisons, j'essaierais de supprimer la fonction de réussite en une fonction définie séparément, puis de créer une fermeture dans l'appel ajax qui inclut le nom de la ville. Tout d'abord, un gestionnaire de succès distinct:

 function city_success(xml, name) { // your success handling code here } 

Ensuite, modifiez la liaison de succès dans l'appel ajax:

 success: function (xml) { city_success(xml, cities[ cityIdx ]); },