2011-04-20 5 views
0

J'essaie de faire des appels ajax imbriqués, mais l'itération ne fonctionne pas: disons que j'ai 2 entreprises avec la société numéro 1 ayant 2 contacts et la société numéro 2 ayant 3 contacts. Je ne peux pas comprendre pourquoi mais le code ci-dessous affiche les deux noms de sociétés suivies par les cinq noms de contact: il est pas imbriqué ....jQuery Ajax appels imbriqués ne fonctionne pas

<script type="text/javascript"> 
    $(function() { 
     $('#searchbutton').bind('click', function (event) { 
      $("#result > h4, #result > p").remove(); 
      $("<p>Loading...</p>").appendTo($("#result")); 
      $.ajax({ 
       type: "GET", 
       dataType: "jsonp", 
       cache: true, 
       url: "http://localhost/archilab/archilabdirectory.svc/", 
       data: ("tag=" + $("#searchstring").val()), 
       success: function (companies) { 
        $("#result > p").remove(); 
        $.each(companies, function() { 
         var outer = this; 
         $("<h4>", { text: outer.Name + " (" + outer.Perimeter + ")" }).hide().appendTo($("#result")).show(4000, function() { 
          $.ajax({ 
           type: "GET", 
           dataType: "jsonp", 
           cache: true, 
           url: "http://localhost/archilab/archilabdirectory.svc/" + outer.Name + "/contacts/", 
           success: function (contacts) { 
            $(contacts).each(function() { 
             $("<p>", { text: this.FirstName + " " + this.LastName }).hide().appendTo($("#result")).show(); 
            }); 
           } 
          }) 
         }); 
        }); 
       } 
      }); 
     }) 
    }); 
</script> 
+3

Au lieu de lancer plusieurs appels ajax, pourquoi ne pas associer les noms et les données de contacts dans une seule réponse JSON pour une seule requête ajax? – Chandu

+3

Et si, pour une raison étrange, vous en avez besoin de deux, s'il vous plaît s'il vous plaît s'il vous plaît écrire des fonctions. Toujours coder DRY (Ne vous répétez pas). Chaque fois que vous pouvez tourner votre code sur le côté et voir les montagnes, vous devez refactoriser. –

Répondre

1

Vous vous rendez compte que vos $.ajax appels sont asynchrones, droit ? Cette each:

$.each(companies, function() { /* ... */ }); 

va ajouter un <h4>, lancer un appel asynchrone $.ajax, puis répétez l'opération pour l'entrée suivante companies. Les appels AJAX seront presque certainement plus longs à terminer que le $.each, donc il va produire le nom de la société <h4> s et puis les appels AJAX finiront et ajouter les <p> s. Il n'y a aucune garantie que les <p> seront ajoutés dans le bon ordre.

Si vous avez besoin que des choses se produisent dans un ordre spécifique, vous devrez ajouter async: false à vos appels $.ajax.

MISE À JOUR: J'ai besoin d'un peu plus d'espace qu'un commentaire. Non, ce n'est pas mon dernier théorème.

Vous pouvez insérer le contenu <h4> dans le gestionnaire de succès interne, mais cela vous laisse toujours ouvert aux problèmes de commande (le second appel AJAX peut se terminer avant le premier). Je pense que la chose la plus facile à faire serait d'ajouter des wrapper <div> s avec des attributs ID autour de vos éléments <h4> et <p>, cela vous donnerait une cible facile pour un appel .append; quelque chose un peu comme ceci:

$.each(companies, function() { 
    var $wrapper_hack = $('<div/>'); 
    $('#result').append($wrapper_hack); 
    add_content($wrapper_hack, outer); 
}); 

// And elsewhere... 
function add_content($wrapper_hack, outer) { 
    $("<h4>", { 
     text: outer.Name + " (" + outer.Perimeter + ")" 
    }).hide().appendTo($wrapper_hack).show(4000, function() { 
     $.ajax({ 
      /* ... */ 
      success: function(contacts) { 
       /* Build your <p> and append it to $wrapper_hack */ 
      } 
     }); 
    }); 
} 

L'idée est d'ajouter du contenu à quelque chose attaché juste à droite <h4> plutôt que de annexant #result; alors, tout apparaîtra dans le bon ordre car vous avez intégré l'ordre correct dans votre imbrication de l'élément HTML. Vous aurez besoin de add_content comme une fonction distincte pour localiser correctement $wrapper_hack et outer juste le contexte désiré et ainsi éviter les problèmes de fermeture habituels.

+0

Vous avez raison, je pense que c'est ce qui se passe, mais comme l'API jQuery dit: "Requêtes inter-domaines et dataType:" les requêtes jsonp "ne supportent pas l'opération synchrone" ... alors quelle serait la meilleure solution? ramener en un appel toutes les entreprises et les contacts ensemble? – momalito

+0

@momalito: La mise à jour de ma réponse est-elle logique? –

+0

Fonctionne très bien, merci beaucoup! Comme mon prototype est 100% orienté client avec des appels REST "atomiques" pour récupérer des données qui correspondent vraiment à mes besoins. Merci encore. – momalito