2014-02-26 63 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不会自动导航到下一页,然后在回调验证函数时,如果数据有效,则向前导航。 –

相关问题