【问题标题】:Waiting for all AJAX call than show dialog box等待所有 AJAX 调用而不是显示对话框
【发布时间】:2015-12-22 15:51:21
【问题描述】:

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

<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 调用完成后显示对话框?

【问题讨论】:

  • 感谢@Lewis 最佳解决方案!

标签: javascript jquery ajax bootbox


【解决方案1】:

跟踪有多少子表单;

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

跟踪已提交的表单数量;

$submittedForms = 0;

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

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

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

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

编辑

您可以跳过全局计时器(因为这可能会超出几毫秒)- 将检查包含在您的 ajax.done 中;

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

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

【讨论】:

  • 对话框代码应该放在哪里?如果签入 ajax.done,如果那里有 0 个子窗体,我还想看到对话框怎么办?
  • @monknom 我不确定你在问什么。我以为您想在子表单提交时显示图像,并且仅在完成时才显示对话框?
  • 对不起,我的英语不好,图片用于提交子表单。但是我想告诉人们整个表单已提交的对话框不仅是子表单
  • 上面的代码不能解决这个问题吗? $submittedForms 和 $subFormsCount 都将 == 0 并因此匹配,应该显示对话框?我不确定我是否完全理解您的问题,也许其他人可以提供进一步的帮助。
  • @monknom 很高兴听到这个消息!祝你的项目好运。
【解决方案2】:

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

 $.ajax({
     url:..,
     type: ..,
     data: /* this subform's data*/ })
     .done(function() {
         //Put code here
     });

【讨论】:

    【解决方案3】:

    你试过.ajaxStop() event handler吗?

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

    另外,请检查this answer

    【讨论】:

      【解决方案4】:

      我假设您有 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.*/
      }
      

      【讨论】:

        【解决方案5】:

        您可以使用$.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/

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-02-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-11
          相关资源
          最近更新 更多