2014-02-26 103 views
1

我知道這個問題可能已經有一百萬次了,但是在我的生活中,我無法得到任何工作。在轉移到其他代碼之前等待Async ajax完成?

我有一個UI嚮導控件,在「changed」事件驗證模型。如果模型無效,則不允許用戶在嚮導中向前移動。我已經厭倦了在jquery中使用$ .when()。done()功能,但是在確保模型有效之前,我的代碼仍然通過。調用異步ajax請求的原因是我不希望UI鎖定,所以我可以顯示某種進度指示器。我已將async屬性設置爲false,但我的UI指示符永遠不會顯示。這裏是我的代碼是做一個例子:

//the change event that is called when the user clicks 'next' on the wizard: 

wizard.on('change', function (e, data) { 
     var isValid = $.validate({ 
          "Model": [The_UI_MODEL], 
          "Url": [URL_To_Server_Validation], 
          "Async": true, //tells ajax request to send as async 
         }); 
     //Tells the wizard not to move 'next' if the request comes back as not valid 
     if (data.direction === 'next' && !isValid) { 

      e.preventDefault(); 
     } 
} 

//我用$ .extend方法jQuery來創建將驗證所有模型在我的系統的功能。

validate: function(options) { 

      //Clear any previous validation errors 
      $.clearValidations(); 

      var data = $.postJson(options); 

      //the result is getting returned before the $.postJson(options) finishes 
      return data.Success; 
     } 

//我創造了我自己的方法,它擴展了$就法,所以我可以請求後/前做其它事情:

postJson: function(options){ 
...other code for my application 
//This is where I want the ajax request to happen and once done return the data coming back 
//This is what I have tried, but it is not doing what I thought. 

$.when(function(){ 
     return $.ajax({ 
       url: options.Url, 
       type: 'POST', 
       cache: false, 
       async: options.Async, 
       timeout: options.Timeout, 
       contentType: 'application/json; charset=utf-8', 
       dataType: "json", 
       data: JSON.stringify(options.Model), 
       error: function(xhr, status, error) { 
        ...do stuff if ajax errors out 
       }, 
       success: function (data) { 

       }, 


      }); 

}).done(function(response){ 
     //looks like i get back the responseText of the request. which is fine, but other posts i have read stated i should be getting back the request itself 
...other UI stuff 
return response; 
}) 



} 
+6

編寫一個函數,執行你的操作,並在成功'success:function(data){...}'中調用該函數... – KarelG

+0

@KarelG,change事件首先觸發,然後驗證。由於ajax請求是異步的,所以立即調用$ .validate函數。 'var isValid'始終爲false – DDiVita

回答

0

KarelG是絕對正確的。您需要重構您的代碼,並在ajax請求的成功回調中進行閾值檢查。

事情是這樣的......

wizard.on('change', function (e, data) { 

    $.ajax({ 
     url: [URL_To_Server_Validation], 
     type: 'POST', 
     cache: false, 
     async: true, 
     contentType: 'application/json; charset=utf-8', 
     dataType: "json", 
     data: {"Model": [The_UI_MODEL]}, 
     success: function (response) { 

      //Tells the wizard not to move 'next' if the request comes back as not valid 
      if(!response & data.direction === 'next') 
      { 
       e.preventDefault(); 
      } 

     } 

    }); 


}); 
+0

這不起作用,導致'e.preventDefault();'成功後發生火災。所以,由於這是一個異步調用,嚮導仍然向前移動。幾乎是我上面遇到的。 – DDiVita

+1

爲什麼不在評估之前評估它呢?它是否有效...是的。運行嚮導更改功能 – heymega

0

它看起來像你想,好像它是同步寫異步代碼。異步調用(例如$ .validate())將立即返回而不帶結果,並繼續執行其餘代碼。任何你想在驗證調用結束時發生的事情都必須在傳遞給它的回調函數中完成。

您可以使用jQuery promises(時,然後完成等)或其他庫(如async.js)來幫助管理控制流。

此外,由於目前幾乎沒有瀏覽器支持,所以這不是特別有用,但yield運算符加上一個庫,如Task.js最終會讓我們編寫異步代碼,就好像它是同步代碼一樣。

+0

正如您在我的代碼中看到的,我嘗試了承諾。這對我沒有用。 – DDiVita

+0

我的要點是關於你試圖從異步調用中返回一個值。在更改事件處理程序中有條件地調用e.preventDefault()將不起作用,因爲必須在執行事件處理程序期間調用e.preventDefault(),但直到處理程序執行一段時間後,$ .validate()纔會有結果已完成運行。相反,您可以始終調用e.preventDefault(),以便UI不會自動導航到下一頁,然後在回調驗證函數時,如果數據有效,則向前導航。 –

相關問題