等待所有AJAX调用而不是显示对话框

时间:2015-12-22 15:51:22

标签: javascript jquery ajax bootbox

我正在开发一个动态的在线表格网站。在主窗体中,我有多个子窗体,可以动态添加和删除。

<div class='subform'>
    //form fields 
    <input ...>
    ...
    <button class='subform_submit'>
</div>

对于每个子表单,我在子表单的提交按钮上绑定一个AJAX调用,如下所示:

$('#main').on('click', '.subform_submit', function(){
    // Get this subform's user input
    ...
    $.ajax({
        url: ..,
        type: ..,
        data: /* this subform's data */
    });
});

因此,在该页面中,我可能有0到10个子表单,具体取决于用户的选择。 我还在页面底部有一个主提交按钮,可以将这些子表单和主表单的数据一起提交。

$('#main').on('click', '#submit', function(e){
    $('.subform_submit').click(); // Submit each subform
    bootbox.confirm({ });
})

单击主提交按钮后,我想显示加载图片,然后显示一个对话框(我在这里使用bootbox.confirm()),直到所有AJAX调用完成。 此对话框告诉用户已提交包含子表单的整个表单。 但问题是,每个AJAX呼叫可能需要2秒钟才能完成,而且我不知道呼叫可能会等待完成。如何编写此主提交按钮以便:

  1. 立即显示加载图片,
  2. 隐藏加载图像并在完成所有AJAX调用后显示对话框?

5 个答案:

答案 0 :(得分:4)

跟踪有多少子表格;

$subFormsCount = $('.subform').length;

跟踪已提交的表单数量;

$submittedForms = 0;

每次表单完成提交时,都会添加到$ submittedForms;

$.ajax({
  ..
  ..
  done: function(){
    $submittedForms++;
  }
})

创建一个全局计时器,以查看提交的表单数是否与子表单总数相匹配。如果为true,则隐藏对话框;

setInterval(function(){
  if($submittedForms == $subFormsCount){
   $('.dialog').show();
  }
}, 50ms)

修改

你可以跳过全局计时器(因为这可能是几毫秒) - 包括检查你的ajax.done;

$.ajax({
  ..
  ..
  done: function(){
    $submittedForms++;

    if($submittedForms == $subFormsCount){
     $('.dialog').show();
    }
  }
})

答案 1 :(得分:2)

您希望使用.done()来指定应等到AJAX异步函数完成的代码。

react-rails

答案 2 :(得分:1)

您是否尝试过.ajaxStop() event handler

$(document).ajaxStop(function() {
  // place code to be executed on completion of last outstanding ajax call here
});

另外,请检查this answer

答案 3 :(得分:0)

我假设您有9个子表单和1个主表单。 8子表格的代码将是相同的。

我在这里使用async:false:表示下一个ajax在第一个未完成之前不会被调用。

示例代码格式:

var id = 5;
$.ajax({
    url:  ,
    type: 'POST',
    data: {'id':id},
    dataType: 'JSON',
    async: false,
    error : function(xhr, textStatus, errorThrown) {
        alert('An error occurred!');
    },
    success : function(response){

    }
});

只需在最后一个子表单中设置变量,即第9个子表单。

success : function(response){
        var counter = true;
    }

if(counter){
    /* Code to show dialog.*/
}

答案 4 :(得分:0)

您可以使用$.when等待每个请求完成。这样的事情应该让你亲近。您基本上希望将所有ajax请求存储在数组中,并将其作为参数传递给when

$('#main').on('click', '.subform_submit', function () {

  var formRequests = $('.subform').map(function () {
    var $form = $(this);
    return $.ajax({
      url: '',
      data: $form.serialzeArray()
    });
  }).get();

  $.when.apply(undefined, formRequests).done(function () {
    console.log('All done!');
  });

});

这是一个非常类似的小演示,我刚刚编写:https://jsfiddle.net/g9a06y4t/