2010-10-12 8 views
4

Je mets en cache les chaînes d'étiquettes en les enregistrant dans une variable, mais en rencontrant des problèmes de portée étranges. Je sais que cela a à voir avec les fermetures, mais je n'arrive pas à comprendre quel est le problème.Problèmes de portée dans jQuery.ajax()

info_lbl = {}; 

$("#chkCorporateGift").click(function(){ 
    var type = $(this).is(":checked") ? "Corporate" : "Personal"; 
    if(!info_lbl.hasOwnProperty(type)){ 
     $.ajax({ 
      url: svc_og + "Get" + type + "InformationLabel", 
      success: function(data){ 
       info_lbl[type] = data; 
      } 
     }); 
    } 
    $("#lblInformationType").text(info_lbl[type]); 
}); 

label lblInformationType est pas défini la première fois des méthodes GetCorporateInformationLabel ou GetPersonalInformationLabel sont appelés. Après la première fois que chacun est appelé, la valeur de l'étiquette est modifiée. Quelqu'un pourrait-il expliquer pourquoi ce comportement se produit? Lorsque j'utilise Firebug et que je place un point d'arrêt sur $("#lblInformationType").text(info_lbl[type]);, info_lbl[type] contient la bonne valeur et tout fonctionne bien sur les deux premiers appels.

Répondre

5

Les appels AJAX sont asynchrones. Cela signifie que tout code suivant la demande pas attendre la demande à retourner avant qu'il s'exécute. En d'autres termes, la requête AJAX ne bloque pas l'exécution des lignes de code suivantes. Ainsi, au moment où la réponse est reçue de la requête AJAX, les lignes de code suivantes ont déjà été exécutées.

Tout code qui repose sur la réponse de la requête AJAX doit être placé à l'intérieur du le rappel.

$("#chkCorporateGift").click(function(){ 
// var type = $(this).is(":checked") ? "Corporate" : "Personal"; 
    // It is more efficient to use this.checked instead of using .is(":checked") 
    var type = this.checked ? "Corporate" : "Personal"; 
    if(!info_lbl.hasOwnProperty(type)){ 
     $.ajax({ 
      url: svc_og + "Get" + type + "InformationLabel", 
      success: function(data){ 
       info_lbl[type] = data; 
        // code that relies on the response needs to be placed in 
        // a callback (or in a function that is called here). 
       $("#lblInformationType").text(info_lbl[type]); 
      } 
     }); 
    } else { 
     $("#lblInformationType").text(info_lbl[type]); 
    } 
}); 

Je voudrais que l'image des choses raison fonctionnent correctement lorsque vous avez un point d'arrêt est que la pause dans l'exécution donne le temps de réponse AJAX pour revenir.


EDIT: Amélioration de l'efficacité du code à l'aide this.checked au lieu du $(this).is(':checked') d'origine.

+0

Merci beaucoup pour votre explication - cela a du sens maintenant. Pourquoi cela est-il plus efficace? – alkos333

+0

@ alkos333 - De rien. : o) Et 'this.checked' est plus efficace car vous lisez directement la valeur de la propriété' checked' (qui sera true/false) de l'élément DOM au lieu de devoir créer un objet jQuery et lancer un ' : check'' filtre contre l'élément, seulement pour finir avec le même résultat. Imaginez si vous aviez une variable locale 'myVar' que vous saviez être' true' ou 'false'. Si vous vouliez utiliser la valeur de myVar, vous le demanderiez. Vous n'exécuterez pas de code qui vérifie si 'myVar' est vrai ou faux, et renvoie true ou false en fonction du résultat du test. : o) – user113716

1

Déplacer cette ligne:

 $("#lblInformationType").text(info_lbl[type]); 

dans le rappel de "succès".

1

Comme dit plus haut, il y a 2 solutions:

1) Faire .ajax $ asynchrones

$.ajax({ 
    url: svc_og + "Get" + type + "InformationLabel", 
    async: false, 
    success: function(data){ 
     info_lbl[type] = data; 
    } 
}); 

2) Keep it asynchrone, mais faire deux fois:

var type = $(this).is(":checked") ? "Corporate" : "Personal"; 
if(!info_lbl.hasOwnProperty(type)){ 
    $.ajax({ 
     url: svc_og + "Get" + type + "InformationLabel", 
     success: function(data){ 
      info_lbl[type] = data; 
      $("#lblInformationType").text(data); 
     } 
    }); 
} 
$("#lblInformationType").text(info_lbl[type]); 
+0

Voulez-vous dire "faire $ .ajax synchrone" dans la solution 1? – AndyG

Questions connexes