2010-10-12 29 views
4

我通過將標籤字符串保存到變量中來緩存標籤字符串,但遇到了奇怪的範圍問題。我知道這與閉包有關,但我似乎無法弄清楚問題究竟在哪裏。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]); 
}); 

lblInformationType標籤沒有被設置的第一次GetCorporateInformationLabel或GetPersonalInformationLabel方法被調用。在第一次調用每一個之後,標籤的值正在改變。有人能解釋爲什麼會出現這種行爲嗎?當我使用Firebug並在$("#lblInformationType").text(info_lbl[type]);上設置中斷點時,info_lbl[type]包含正確的值,並且前兩次調用中的一切正常工作。

回答

5

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')代碼改進效率。

+0

謝謝你這麼多爲了您的解釋 - 現在這是有道理的。然而,爲什麼this.checked更高效呢? – alkos333 2010-10-12 21:39:45

+0

@ alkos333 - 不客氣。 :o)'this.checked'效率更高,因爲您直接讀取DOM元素的'checked'屬性(這將是true/false)的值,而不必創建jQuery對象並運行' :針對元素檢查過濾器,只會得到相同的結果。想象一下,如果你有一個本地變量'myVar',你知道它是'true'或'false'。如果你想使用'myVar'的值,你只需要它。你不會運行一些測試'myVar'是真還是假的代碼,並根據測試結果返回true或false。 :o) – user113716 2010-10-12 21:50:00

1

移動這一行:

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

到 「成功」 的回調。

1

正如上面所說的,有2個解決方案:

1)使$就異步

$.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]); 
+0

您的意思是解決方案1中的「製作$ .ajax同步」嗎? – AndyG 2010-10-12 20:31:48