开发者

Scoping Issues inside jQuery.ajax()

开发者 https://www.devze.com 2023-01-20 10:09 出处:网络
I\'m caching label strings by saving them into a variable, but running into weird scoping issues. I know this has to do with closures, but I can\'t seem to figure out what the issue is exactly.

I'm caching label strings by saving them into a variable, but running into weird scoping issues. I know this has to do with closures, but I can't seem to figure out what the issue is exactly.

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]);
});

lblInformationType label isn't set the very first time GetCorporateInformationLabel or GetPersonalInformationLabel methods are called. After the first time each one is called, the label's value is being changed. Could somebody please explain why this behavior occurs? When I use Firebug and set a break point on $("#lblInformationType").text(info_lbl[type]);, info_lbl开发者_开发技巧[type] contains the right value and everything works fine on the first two calls as well.


AJAX calls are asynchronous. This means that any code following the request does not wait for the request to return before it runs.

In other words, the AJAX request does not block execution of subsequent lines of code. So by the time the response is received from the AJAX request, the following lines of code have already executed.

Any code that relies on the response of the AJAX request should be placed inside the callback.

$("#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]);
    }
});

I would image that the reason things work properly when you have a breakpoint is that the pause in execution gives the AJAX response time to return.


EDIT: Improved efficiency of the code by using this.checked instead of the original $(this).is(':checked').


Move this line:

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

into the "success" callback.


As said above, there is 2 solutions :

1) Making $.ajax asynchronous

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

2) Keep it asynchronous but doing twice :

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

精彩评论

暂无评论...
验证码 换一张
取 消