2014-09-01 26 views
1

我遇到了一些JavaScript的問題,它旨在顯示基於C#ViewModel的JQUERY對話框。使用AJAX調用的JavaScript對話框不同步

我有一個ASP下拉內顯示「註冊日期」信息的中繼器。這個想法是,當用戶從列表中選擇一個日期時,JavaScript對話框將顯示一個更加圓整的與使用特定視圖模型屬性進行註冊相關的信息摘要。對於有問題的頁面,在標準$(document).ready上調用CustomerSummary函數。

JS代碼

function CustomerSummary() { 

    var registrationId; 
    var data; 

    $("select[id$='ddlRegistration']").change(function() { 
     registrationId = $(this).val(); 

     if (registrationId !== 'default') 
     { 
      data = MakeAJAXCall(registrationId); 
      $("#dialog").html("Registration Id: " + data.RegistrationId + "<br />" + 
           "Permit From: " + data.PermitFrom + "<br />" + 
           "Permit To: " + data.PermitTo + "<br />" + 
           "Registration Status: " + data.RegistrationStatus 
      ); 

      $("#dialog").dialog({ 

       show: { 
        effect: "blind", 
        duration: 1000 
       }, 

       hide: { 
        effect: "explode", 
        duration: 1000 
       } 
      }); 
     } 
    }); 

    function MakeAJAXCall(regId) 
    { 
     $.ajax({ 
      type: "post", 
      contentType: "application/json; charset=utf-8", 
      dataType: "text json", 
      url: "/Secure/CustomerSummary.aspx/GetRegistration", 
      data: "{ regId: \"" + regId + "\" }", 

      success: function (msg) {     
       data = msg.d;     
      }, 

      error: function (xOptions, textStatus) 
      {     
       console.log(textStatus); 
       console.log(xOptions); 
      } 
     }); 
    }  
} 

C#代碼

[WebMethod(), ScriptMethod(UseHttpGet=false)] 
     public static RegistrationViewModel GetRegistration(int regId) 
     {    
      RegistrationRepository repo = new RegistrationRepository(); 
      RegistrationViewModel reg = new RegistrationViewModel(); 
      RegistrationFactory regFac = new RegistrationFactory(); 

      reg = regFac.ConvertToRegistrationViewModel(repo.GetRegistration(regId)); 

      return reg; 
     } 

什麼是調試

這裏發生的事情是在這條線時發生的事情:

$("#dialog").html("Registration Id: " + data.RegistrationId + "<br />" + 

,我發現了錯誤:

Uncaught TypeError: Cannot read property 'RegistrationId' of undefined 

我第一次從菜單中選擇和改變功能的日期被調用時,我得到上面的錯誤消息,並且不會出現對話框,如果我檢查data我確實可以看到它是未定義的。然後,一旦我從下拉菜單中選擇了不同的數據,並且我打破了我的斷點(change.(function)數據被設置爲從先前的AJAX調用中檢索到的數據,對話框隨即彈出,但與之前的請求數據一起,結果停留在這個循環中,每次我選擇一個數據時,我都會看到前面的選擇信息。

任何人都可以指出,爲什麼我經常選擇一個不同步,我相信它是由於第一個更改請求,但我不明白爲什麼AJAX調用不會將data設置爲期望的結果,直到我選擇下一個下拉項目。

回答

3

因爲MakeAJAXCall正在執行一個Ajax調用這將無法正常工作

data = MakeAJAXCall(registrationId); 

,它是異步的回報率將不會以相同的順序爲您在函數返回執行。所以,你需要使用回調。

嘗試使用此方法更改您的代碼是這樣的:

MakeAJAXCall(registrationId, function(data){ 
$("#dialog").html("Registration Id: " + data.RegistrationId + "<br />" + 
            "Permit From: " + data.PermitFrom + "<br />" + 
            "Permit To: " + data.PermitTo + "<br />" + 
            "Registration Status: " + data.RegistrationStatus 
       ); 
}); 

然後在你的Ajax調用,你需要做出這一更改:

function MakeAJAXCall(regId, callback) 
    { 
     $.ajax({ 
      type: "post", 
      contentType: "application/json; charset=utf-8", 
      dataType: "text json", 
      url: "/Secure/CustomerSummary.aspx/GetRegistration", 
      data: "{ regId: \"" + regId + "\" }", 

      success: function (msg) {     
       data = msg.d; 
       callback(data); //<--- You callback function is called here    
      }, 

      error: function (xOptions, textStatus) 
      {     
       console.log(textStatus); 
       console.log(xOptions); 
      } 
     }); 
    }  
2

第一個在Ajax是異步的。這意味着你的電話會在後臺運行,這就是你使用回調的原因。當你的通話成功/失敗完成後,說10秒後,調用正確的功能。與此同時,您設置並創建結果的其他代碼也會運行,很可能在從ajax查詢收到任何答案之前運行。正如@Dalorzo所建議的那樣,在回調中包含結果對話框代碼,以便在收到結果後,您的代碼將運行