正在运行ajax进程时在启动箱中显示加载消息?

问题描述 投票:0回答:2

我的应用程序中有显示状态的页面。状态显示在带有两个选项Active/Inactive的下拉菜单中。用户只需单击菜单并选择选项,即可更改状态。对于该过程,我使用JQuery / Ajax onchange触发器来跟踪状态更改。该代码工作正常,并将该值保存在数据库中。我遇到的问题与bootbox和显示加载消息有关。当用户单击菜单并更改状态时,ajax将发送请求。此时,对话框窗口将显示在用户屏幕上,并带有加载消息。一旦ajax请求完成,加载对话框将隐藏并显示消息,提示用户状态已成功保存。这是代码示例:

function alertBox(title, message, size) {
  title = title || "Alert";
  message = message || "Alert Box";
  size = size || "lg";

  bootbox.alert({
    size: size,
    title: title,
    message: message
  });
};

$('.status').on('change', function() {
  let $curr_fld = $(this),
    status_id = $curr_fld.attr('data-id'),
    dialog = bootbox.dialog({
      message: '<p class="text-center mb-0"><i class="fa fa-spin fa-cog"></i> Loading...</p>',
      closeButton: false
    });

  $curr_fld.prop("disabled", true);
  /*** Start: This is a code for testing. ***/
  /*
  setTimeout(function() {
    dialog.modal('hide');
    $curr_fld.prop("disabled", false);
    alertBox('Alert Message', status_id);
  }, 3000);
  */
  /*** End: This is a code for testing. ***/
  
  $.ajax({
    type: 'POST',
    url: 'test.php?id=1',
    data: {
      'status_id': status_id
    },
    dataType: 'json'
  }).done(function(obj) {
    dialog.modal('hide');
    $curr_fld.prop("disabled", false);
    if (obj.status === 200) {
      alertBox('Alert Message', obj);
    } else {
      alertBox('Alert Message', obj);
    }
  }).fail(function(jqXHR, textStatus, errorThrown) {
    $curr_fld.prop("disabled", false);
    alertBox('Error', textStatus);
  });

});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/5.4.0/bootbox.min.js"></script>

<table class="table table-striped table-bordered" id="tbl_nofa">
  <thead>
    <tr class="bg-dark">
      <th class="text-center text-white">Section</th>
      <th class="text-center text-white">Status</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="text-center"> South</td>
      <td class="text-center">
        <select class="custom-select status" name="status_1" id="status_1" data-id="1">
          <option value="A" selected>Active</option>
          <option value="I">Inactive</option>
        </select>
      </td>
    </tr>
    <tr>
      <td class="text-center"> North</td>
      <td class="text-center">
        <select class="custom-select status" name="status_2" id="status_2" data-id="2">
          <option value="A">Active</option>
          <option value="I" selected>Inactive</option>
        </select>
      </td>
    </tr>
    <tr>
      <td class="text-center"> East</td>
      <td class="text-center">
        <select class="custom-select status" name="status_3" id="status_3" data-id="3">
          <option value="A" selected>Active</option>
          <option value="I">Inactive</option>
        </select>
      </td>
    </tr>
    <tr>
      <td class="text-center"> West</td>
      <td class="text-center">
        <select class="custom-select status" name="status_4" id="status_4" data-id="4">
          <option value="A">Active</option>
          <option value="I" selected>Inactive</option>
        </select>
      </td>
    </tr>
  </tbody>
  <tfoot>
    <tr class="bg-dark">
      <th class="text-center text-white">Section</th>
      <th class="text-center text-white">Status</th>
    </tr>
  </tfoot>
</table>

如果您运行上面的代码示例,则一旦ajax请求完成,就会在屏幕上看到加载对话框。我不确定为什么要使用.modal('hide')。如果使用setTimeout注释掉代码块并注释掉ajax代码,您将看到加载对话框可以正常工作。如果有人知道如何解决此问题,请告诉我。

javascript jquery ajax bootstrap-4 bootbox
2个回答
1
投票

您需要从ajax调用的always功能关闭对话框。测试失败时会发生,但是您没有代码可以关闭对话框。但是,这仍然不能解决问题。

  1. 这似乎是boostrap模态的问题。发生的情况是在动画完成之前过早调用了hide函数。有两种解决此问题的方法:
  2. 使用animate: false禁用动画。

    1. 添加检测动画是否完成的代码,如果还没有,请在always函数中适当地执行操作。
  • $('.status').on('change', function() { let $curr_fld = $(this), loading_shown = false, status_id = $curr_fld.attr('data-id'), dialog = bootbox.dialog({ // animate: false, // <-- simple way that makes the issue go away. message: '<p class="text-center mb-0"><i class="fa fa-spin fa-cog"></i> Loading...</p>', closeButton: false, }).on('shown.bs.modal', () => loading_shown = true); $curr_fld.prop("disabled", true); $.ajax({ type: 'POST', url: 'test.php?id=1', data: { 'status_id': status_id }, dataType: 'json' }).done(function(obj) { $curr_fld.prop("disabled", false); if (obj.status === 200) { alertBox('Alert Message', obj); } else { alertBox('Alert Message', obj); } }).fail(function(jqXHR, textStatus, errorThrown) { $curr_fld.prop("disabled", false); alertBox('Error', textStatus); }).always(() => { // hide immediately, or wait until the animation is complete by listening // to shown.bs.modal. loading_shown ? dialog.modal('hide') : dialog.on('shown.bs.modal', () => dialog.modal('hide')); }); });
  • 可能有更简洁的方法来处理动画问题而不禁用动画本身。这只是一种方法。
  • © www.soinside.com 2019 - 2024. All rights reserved.