2009-11-04 102 views
5

我正在对表单数据进行验证,这样当有人点击提交按钮时,它首先检查表单的内容。许多字段(可能为零,可能不止一个,取决于页面)具有独特代码之类的事情,这些代码需要先与服务器进行检查。我正在对服务器运行一个异步请求,该请求只响应每个字段的'ok'或'taken'。如果任何字段有错误,则页面不提交。jQuery AJAX:收集多个异步结果

一方面,这应该是异步的:它应该继续验证其余的表单字段,而该请求处于关闭状态,包括触发其他请求。如果通话是同步进行的,那么它会明显减慢后面字段的反馈速度。

另一方面,我想要确保所有的验证请求已经返回(或超时),然后才对validate()方法回复“是”或“否”,并允许提交进行与否。因此,如果有两个字段需要验证,那么validate()方法应该关闭这两个AJAX请求,处理剩余的字段,然后等到这两个请求返回后再返回。

我可以用一些丑陋的家庭烘焙解决方案(可能涉及代表正在进行中的请求的随机ID数组)来实现这一点,但在我做之前,有任何内置函数,插件或标准技术,我应该改用?


澄清

我想我需要的是一个方法之前使代码等待结果从一个或多个异步请求。这与回调不同,因为方法的结果取决于请求的结果。它与同步请求不同,因为它们可能不止一个。

我使用这个在提交前检查形式:

$("form").submit(function() { 
    return validate($(this)); 
}); 

如果validate()方法返回false,那么表单不提交。 validate() hilights任何不被接受的字段。对于一般的领域,validate()看起来是这样的(大大简化版本,没有反馈):

function validate(form) { 
    resetWarnings(form); 
    var ok = true; 

    // required fields 
    form.find("input.required").each(function() { 
     var field = $(this); 
     if (field.val() === "") { 
      ok = false; 
     } 
     return this; // meaningless in this case but a good habit to keep 
    }); 

    // fields that matches a pattern 
    form.find("input.pattern").each(function() { 
     var field = $(this); 
     var pattern = field.data("pattern"); 
     if (!field.val().match(pattern)) { 
      ok = false; 
     } 
     return this; 
    }); 

    // various other rules for other sorts of field 
    ... 

    return ok; 
} 

对于AJAX领域它更像是这样的:

form.find("input.lookup").each(function() { 
     var field = $(this); 
     var url = field.data("lookup"); 
     $.ajax({ 
      url: url, 
      data: { code: field.val() }, 
      success: function (result) { 
       if (result === "taken") { 
        ok = false; 
       } 
      } 
     } 
    }); 

但当然,validate()已经前完成成功的方法被称为。所以如果我可以在返回前等待ajax完成(成功或者错误),我可以得到正确的结果并停止提交的表单。如果我使ajax同步,那么整个方法会停止,直到完成为止,这是错误的。


进一步思考

给了JavaScript的线程模型(这是说完全没有),就是我所要求的技术上是不可能的?

回答

1

如果我正确理解你,你想检查值(1 ..*)在表单中输入之前是唯一的,一旦用户在表单上执行发布之前点击提交按钮。如果是这样的话,我会创建一个JSON数组的字段和值,并一次发送 - 所以你只是在等待一个响应。这应该很容易使用jQuery的'each'函数和使用jQuery ajax。

然后,您可以在发布表单之前检查单个结果。

这可能不言而喻,但要确保在发布后重复相同的验证服务器,以避免与其他用户竞争。

在用户完成表单,您可以验证各个领域,并存储结果,但这将是signficantly更健谈(可伸缩性原因,你应该考虑带宽),你暴露自己发生故障的服务器端验证的机会更大。

+0

它不是一系列相同的唯一字段,但表单上的多个字段可能需要服务器端检查 - 在不同的URL上针对不同的检查。实际上,多位并不重要 - 它使validate()方法等待异步结果。我强调可能有多个字段的唯一原因是,使单个同步呼叫不是一个有效的答案。 – 2009-11-04 19:36:59

+0

请参阅说明。 – 2009-11-04 20:07:24

+0

我不确定我要求什么是可能的。在用户完成表单时验证字段可能最终成为唯一的方法。 – 2009-11-04 20:21:07

0

如何使用.ajaxStop:如果的validate()本身涉及的AJAX调用解除绑定需要

$(document).ajaxStop(function() { 
    $(this).unbind("ajaxStop"); 
    // run validate method here 
    }); 
    //run asynchronous validations here 

注意。

3

使用jQuery 1.5+从多个异步请求中收集结果数据的最佳方法是使用表示这些请求及其状态的Deferred对象,以及包装函数$ .when(...)。then(allRequestsCompleteCallback(), someRequestFailedCallback())

这有助于避免使用多个嵌套的回调函数,使您的代码更清洁,更易于维护。

的JavaScript/jQuery的例子:

function ajax1() { return $.ajax({ url: 'server1.php' }) } 
function ajax2() { return $.ajax({ url: 'server2.php' }) } 

$.when(ajax1(), ajax2()).then(
    function() { 
     // ajax1 AND ajax2 succeeded 
    }, 
    function() { 
     // ajax1 OR ajax2 succeeded 
    } 
); 

检查更多的文档和例子在这里:

+0

有没有办法做到这一点,而不事先知道你会有多少延期物件?例如,当多个请求是由于以恒定长度的块分割一个未知长度的大数组? – learn2day 2017-10-04 15:40:51