【问题标题】:Scoping Issues inside jQuery.ajax()jQuery.ajax() 中的范围问题
【发布时间】:2010-10-12 19:19:59
【问题描述】:

我通过将标签字符串保存到变量中来缓存它们,但遇到了奇怪的范围问题。我知道这与闭包有关,但我似乎无法弄清楚到底是什么问题。

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

第一次调用 GetCorporateInformationLabel 或 GetPersonalInformationLabel 方法时未设置 lblInformationType 标签。在第一次调用每个标签后,标签的值正在更改。有人可以解释为什么会发生这种行为吗?当我使用 Firebug 并在 $("#lblInformationType").text(info_lbl[type]); 上设置断点时,info_lbl[type] 包含正确的值,并且在前两个调用中一切正常。

【问题讨论】:

    标签: javascript jquery ajax closures


    【解决方案1】:

    AJAX 调用是异步的。这意味着请求之后的任何代码都不会在运行之前等待请求返回。

    换句话说,AJAX 请求不会阻止后续代码行的执行。因此,当收到来自 AJAX 请求的响应时,以下代码行已经执行。

    任何依赖于 AJAX 请求响应的代码都应该放在内部回调中。

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

    我想,当你有一个断点时,事情正常工作的原因是执行中的暂停让 AJAX 响应时间返回。


    编辑:使用this.checked 代替原来的$(this).is(':checked') 提高了代码效率。

    【讨论】:

    • 非常感谢您的解释 - 现在这很有意义。然而,为什么 this.checked 更有效?
    • @alkos333 - 不客气。 :o) 而this.checked 更高效,因为您直接读取 DOM 元素的 checked 属性(将是真/假)的值,而不必创建 jQuery 对象并运行 :checked过滤元素,最终得到相同的结果。想象一下,如果你有一个局部变量 myVar,你知道它是 truefalse。如果您想使用myVar 的值,您只需请求即可。您不会运行一些代码来测试myVar 是真还是假,并根据测试结果返回真或假。 :o)
    【解决方案2】:

    移动这一行:

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

    进入“成功”回调。

    【讨论】:

      【解决方案3】:

      如上所述,有两种解决方案:

      1) 使 $.ajax 异步

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

      2) 保持异步但执行两次:

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

      【讨论】:

      • 您的意思是在解决方案 1 中“使 $.ajax 同步”吗?
      猜你喜欢
      • 2010-09-24
      • 2017-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-28
      • 2014-01-28
      • 2021-11-09
      • 1970-01-01
      相关资源
      最近更新 更多