2012-11-05 58 views
0

背景
這是在延續我的問題Correct way to set up a sequence of synchronous/asynchronous functions all of which can stop form submission and further processing?使用延遲與jQuery Ajax調用,並與用戶確認

我對什麼是正確的方法(遞延管)的答案之間的讀取沿異步流程,但我仍然無法實際執行此操作。我今天剛開始閱讀jQuery延期API,但我還沒有掌握很多。舉個小例子來說,jQuery API文檔看起來太複雜了。任何人都可以鏈接到一些基本的演示/教程關於這個?我需要一個啓動在這裏。

詳細信息
我有這個項目中使用的jQuery版本1.6。

考慮這個例子 - 當用戶點擊表單提交按鈕 -
1.運行validateInventory()。
a。如果驗證失敗,則向用戶顯示確認對話框(如果用戶同意)(請轉到步驟2)

b。如果驗證通過(請轉至步驟2)
2.運行preValidateUrls()。
a。如果驗證失敗,則向用戶顯示確認對話框(如果用戶同意)(請轉到步驟3)

b。如果驗證通過(請轉至步驟3)
3.提交表單。

以下是我有異步函數的結構 -

注意,這個功能也有內部的,如果(確認)塊。閱讀我的問題2

function validateInventory() 
    { 
     $.ajax({ 
      type: "POST", 
      url: posturl+"?"+params, 
      dataType: "json", 
      success: function(res) 
       { 
        if(!res.success) 
        { 
          //display some confirmation dialog, if user agrees con 
          if(confirm(msg)) 
          { 
           //continue with next validation step 
          } 
        } 
        else 
        { 
          //validation success - so continue with next validation step 
        } 
       } 
      }); 
    } 

    //similar logic as inside validateInventory() 
    function preValidateUrls() 
    { 


    } 

我還可能有一些同步驗證函數(客戶端僅邏輯)在驗證邏輯,在該序列的任何地方 -

function syncVal() 
{ 
    return true/false 
} 

問題1如若語法用於使這樣的函數也類似於異步函數?

問題2如何處理顯示確認對話框(如果驗證失敗)並僅在用戶確認後才進行下一個驗證步驟。是否應該重新調整功能?需要將if(confirm)塊移到外面?

在那裏我有很多達到了迄今爲​​止

好不算什麼,我想我需要使用.when.done的API。

回答

1

如果我理解正確的步驟1,2,3,然後你想要的邏輯可以被編碼是這樣的:

$(function() { 
    function validateInventory(form) {//`form` is passed conventionally at the left hand end of the pipe chain. 
     var dfrd = $.Deferred();//A Deferred object to be resolved/rejected in response to ajax success/error. 
     var params = .....;//use values from `form` as required 
     $.ajax({ 
      type: "POST", 
      url: posturl + "?" + params, 
      dataType: "json" 
     }).done(function(res) {//ajax success 
      if(res.success || confirm(msg1)) { dfrd.resolve(form); }//Here we resolve dfrd, passing `form` in order to make `form` available to the next function in the pipe chain. 
      else { dfrd.reject("validateInventory() failed (not verified)"); }//Application error. By rejecting with a specific message, we have the means of knowing where the failure occurred. 
     }).fail(function(jqXHR, textStatus, errorThrown) {//ajax error 
      dfrd.reject("validateInventory() failed (textStatus)");//Again, a specific message. 
     }); 
     return dfrd; 
    } 

    //Similar logic as inside validateInventory() 
    function preValidateUrls(form) {//The form, is piped through by the statement `dfrd.resolve(form);` in validateInventory 
     var dfrd = $.Deferred(); 
     var params = .....; 
     $.ajax({ 
      type: "POST", 
      url: posturl + "?" + params, 
      dataType: "json" 
     }).done(function(res) { 
      if(res.success || confirm(msg2)) { dfrd.resolve(form); } 
      else { dfrd.reject("preValidateUrls() failed (not verified)"); } 
     }).fail(function(jqXHR, textStatus, errorThrown) { 
      dfrd.reject("preValidateUrls() failed (textStatus)"); 
     }); 
     return dfrd; 
    } 

    //This is the function to be called if the various stages of validation were successful. 
    function overallSuccess(form) { 
     form.submit(); 
    } 

    //This is a common error handler, which will be called if either of the validation stages fail. 
    function errorHandler(message) { 
     alert(message);//or whatever 
    } 

    var myForm = $("form").get(0);//for example 

    //And now the glue that puts the component parts together. 
    validateInventory(myForm).pipe(preValidateUrls, errorHandler).pipe(overallSuccess, errorHandler); 
}); 

未經檢驗

有關說明,請參閱代碼中的註釋。

整個事情可以被分解成任何數量的不同方式。我會選擇按照上面的方式對它進行編碼,因爲組件部分是分離的和清晰的,「粘合」語句(管道鏈)非常簡潔並且易於擴展以適應進一步的驗證步驟。使用其他方法,您往往會深入嵌套難以遵循的功能,特別是對於將來需要維護代碼的人。

+0

感謝您的回答。我測試了它,它工作得很好!儘管我在開始時看起來很難,但我希望看到其他選擇。您的解決方案需要在每個函數內部進行更改(必須啓動'$ .Deferred()'對象並添加'dfrd.resolve()'和'dfrd.reject()')。我不會介意粘貼聲明有一些額外的代碼.. –

+0

Sandeepan,自從我發佈我的答案後,事情已經發生。實際上,'.pipe()'在2012年12月已經被棄用了。從jQuery 1.8開始,我們都應該使用修改後的'.then()'。你可以嘗試用'.then'代替'.pipe',看看它是否仍然有效。 –