2009-04-06 8 views
0

Une partie de la routine de rappel asynchrone jQuery/ajax m'a toujours dérouté, et je suis sûr que c'est juste parce que je ne connais pas assez javascript.Pageloads asynchrones - Comment passez-vous les paramètres aux callbacks?

Simplifier le code en bas, autant que possible, c'est là que je suis coincé:

Si je crée un vide div avec un id de « queuediv1 » je peux le remplir avec les résultats d'une méthode page comme ce.

$(document).ready(function() { 
    $.ajax({ 
     type: "POST", 
     contentType: "application/json; charset=utf-8", 
     dataType: "json", 
     url: "test12.aspx/GetHtmlTest", 
     //data: "{ 'Dividend': '" + $("#Dividend").val() + "' }", 
     data: "{}", 
     // Error! 
     error: function(xhr, status, error) { 
      // Boil the ASP.NET AJAX error down to JSON. 
      //var err = eval("(" + xhr.responseText + ")"); 

      // Display the specific error raised by the server 
      //alert(err.Message); 
      alert("AJAX Error!"); 
     }, 
     success: function(msg) { 
     $("#queuediv1").removeClass('isequeue_updating'); 
     $("#queuediv1").html(msg); 
      //an unorderd list with the tag "browserxx" was just inserted into the div 
     $("#browserxx").treeview(); 
     } 
    }); 
}); 

Cela fonctionne très bien; ce n'est pas le bloc, et cela me donne le contrôle total de la gestion des erreurs. Cependant, quand j'essaie d'étendre cela, j'ai des ennuis. Si j'ai plusieurs zones de la page que je veux mettre à jour, je peux modifier l'appel afin que chaque appel asynchrone soit fait avec les "données" correctes, mais je ne peux pas dire au callback l'ID du contrôle que je le veux peupler.

mon cas Simplifier à quelque chose qui est encore cassé:

Supposons qu'il y ait 4 divs dans le DOM avec queuediv1 de id, queuediv2, queuediv3 et queuediv4 que je veux mettre à jour. Je voudrais réutiliser autant de code que possible. Alors que le nombre et id de divs être mis à jour sera en réalité dynamique, je pensais que cela aurait fonctionné:

$(document).ready(function() { 
for (i= 1;i<=4;i++) 
{ 
    var divname ="#queuediv"+i; 

    $.ajax({ 
     type: "POST", 
     contentType: "application/json; charset=utf-8", 
     dataType: "json", 
     url: "test12.aspx/GetHtmlTest", 
     // data would be populated differently so that each div gets its own result- for now it doesn't matter 
     //data: "{ 'Dividend': '" + $("#Dividend").val() + "' }", 
     data: "{}", 
     // Error! 
     error: function(xhr, status, error) { 
      // Boil the ASP.NET AJAX error down to JSON. 
      //var err = eval("(" + xhr.responseText + ")"); 

      // Display the specific error raised by the server 
      //alert(err.Message); 
      alert("AJAX Error!"); 
     }, 
     success: function(msg) { 
     $(divname).removeClass('isequeue_updating'); 
     $(divname).html(msg); 
     $("#somethingfromthemsg").treeview(); 
     } 
    }); 
} 
}); 

Mais cela ne peut jamais travailler depuis le succès de temps est appelé la portée est fausse et la divname est déjà égal à "# queuediv4" pour chaque callback. Seulement ce div est mis à jour (4x). Existe-t-il un moyen de transmettre une variable au rappel? Ou suis-je juste en train de penser au problème?

Je n'ai trouvé quelque chose comme répondant à des appels à $ async .getJSON ici: http://thefrontiergroup.com.au/blog/tag/jquery

Ce site a parlé de l'emballage le rappel dans une autre fonction anonyme pour préserver les variables d'appel. Cela avait un sens pour la portée, mais je n'ai aucune idée de la façon de créer l'appel $ .ajax.

Répondre

1

Vous pouvez envelopper chaque itération de la boucle dans une fonction anonyme comme ceci:

$(document).ready(function() { 
for (i= 1;i<=4;i++) 
{ 
(function(){ 
    var divname ="#queuediv"+i; 

    $.ajax({ 
     type: "POST", 
     contentType: "application/json; charset=utf-8", 
     dataType: "json", 
     url: "test12.aspx/GetHtmlTest", 
     data: "{}", 
     error: function(xhr, status, error) { 
      alert("AJAX Error!"); 
     }, 
     success: function(msg) { 
     $(divname).removeClass('isequeue_updating'); 
     $(divname).html(msg); 
     $("#somethingfromthemsg").treeview(); 
     } 
    }); 
})(); 
} 
}); 

Un exemple beaucoup plus simple serait:

<div id="output1"></div><div id="output2"></div><div id="output3"></div><div id="output4"></div><div id="output5"></div> 
<script language="javascript"> 
for(var a=1; a<=5; a++) { 
    (function(){ 
    var divName = "output" + a; 
    var b = a; 
    setTimeout(function(){document.getElementById(divName).innerHTML = b;}, 2000); 
    })(); 
} 
</script> 
+0

C'était exactement ce que je cherchais Merci! – Jim

1

Rappelez-vous que JavaScript est un vrai langage fonctionnel, et toutes les fonctions (anonymes ou non) sont vraiment complètes closures, donc les variables de 'outside' une fonction sont toujours disponibles.

une méthode générique pour résoudre les 'paramètres' en passant est la construction d'exécution de la fermeture:

function makeSuccessFunc (divname) { 
    return function (msg) { 
     $(divname).removeClass('isequeue_updating'); 
     $(divname).html(msg); 
     $("#somethingfromthemsg").treeview(); 
    }; 
}; 

afin que vous puissiez faire:

$(document).ready(function() { 
for (i= 1;i<=4;i++) 
{ 
    var divname ="#queuediv"+i; 

    $.ajax({ 
     type: "POST", 
     contentType: "application/json; charset=utf-8", 
     dataType: "json", 
     url: "test12.aspx/GetHtmlTest", 
     // data would be populated differently so that each div gets its own result- for now it doesn't matter 
     //data: "{ 'Dividend': '" + $("#Dividend").val() + "' }", 
     data: "{}", 
     // Error! 
     error: function(xhr, status, error) { 
      // Boil the ASP.NET AJAX error down to JSON. 
      //var err = eval("(" + xhr.responseText + ")"); 

      // Display the specific error raised by the server 
      //alert(err.Message); 
      alert("AJAX Error!"); 
     }, 
     success: makeSuccessFunc (divname) 
    }); 
} 
}); 
Questions connexes