2012-11-05 59 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',看看它是否仍然有效。 –