如何从 ajax/error 回调中刷新数据表?

How to refresh DataTables from within ajax/error callback?

我正在像这样扩展 DataTables 默认设置:

$.extend(true, $.fn.dataTable.defaults, {
    lengthChange: false,
    deferRender: true,
    displayLength: 25,
    stateSave: false,
    serverSide: true,
    processing: true,
    ajax: {
        type: 'POST',
        error: function($xhr) {
            if($xhr.status === 401) {
                wxu.openLoginBox(function(data) {
                    // HELP: how can I get the DataTables object from this context?
                });
            } else {
                wxu.notify({'text': "Could not load list", 'cssClass': 'error', timeout: 0});
            }
        }
    }
});

有时用户会被注销,然后当他们尝试更改页面或排序时,它只会永远显示 "Processing"。我可以通过查找 401 错误响应(这是我的应用程序在您超时时发送的内容)来捕获它,但是我不知道如何 "refresh" dataTables 来制作 "Processing" 消息消失,以便您可以继续使用该应用程序。

请注意,我在 .js 文件中扩展了这里的默认值 -- 我不知道此时 DataTables 将绑定到哪个元素。

如何从 ajax/error 回调中 "fix" dataTables?

the documentation, ajax can be a function. It is called with the table settings object, which can be used to construct a new API object for the table. Then, you can just use the API method to get the processing element (using .dataTables_processing) or take whatever other action you like using the other available API methods。具体来说,像这样的东西应该有效:

{
  "ajax": function (data, callback, settings) {
    $.ajax({
      type: "POST",
      success: function (json) {
        callback(json);
      },
      error: function ($xhr) {
        if ($xhr.status === 401) {
          var api = new $.fn.dataTable.Api(settings);
          var container = api.table().container();
          $(container).find('.dataTables_processing').hide();
        }
      }
    });
  }
}

我没有看到它的具体记录,但是 this 在调用 ajax 函数时也被设置为 DataTable 对象。使用它可能是实现目标的更直接途径,但我认为以上内容更符合预期用途。

NOTES

您不应覆盖 ajax.error,因为此 属性 由 DataTables 在内部使用,这同样适用于 ajax.success

SOLUTION

您可以为 xhr 事件添加事件处理程序以处理 Ajax 错误 (json === null)。

// Prevent alert message from being displayed
$.fn.dataTable.ext.errMode = 'none';

// Use delegated event handler
// to handle Ajax request completion event
$(document.body).on('xhr.dt', function (e, settings, json, xhr){
   // If there is an Ajax error and status code is 401
   if(json === null && xhr.status === 401){         
      var api = new $.fn.dataTable.Api(settings);

      console.log('Session expired');
/*     
      wxu.openLoginBox(function(data){
          api.ajax.reload();
      });
*/

   } else {
      console.log('Could not load list');   
/*       
       wxu.notify({'text': "Could not load list", 'cssClass': 'error', timeout: 0});
*/       
   }
});

DEMO

有关代码和演示,请参阅 this jsFiddle