小编典典

DataTables-启动一个新的Ajax请求

ajax

我在服务器端模式下使用DataTables 1.10.15。

我通过ajax将表单的内容传递给PHP脚本,以使其搜索数据库:

 var myTable = $('#myTable').DataTable( {
    "processing": false,
    "serverSide": true,
    "searching": false,
    "ajax": { 
        "url" : "/getData.php",
        "data" : function ( d ) {
            // Search input data
            d.field1 = $('#field1').val(),
            d.field2 = $('#field2').val(),
            d.field3 = $('#field3').val()
        },
        "method" : "POST",
    }
 });

我还有其他一些js,它会在将ajax请求发送到之前检查至少3个字符是否输入到字段中/getData.php

这意味着-输入3个字符后- 每次 按下一个键都会发出一个ajax请求,因此可能会有ajax请求队列。

$('#primarySearch input[type="text"]').on({
    "keyup": function(e) {
      // Ignore tab key.
      if (e.which != 9) {
        processPrimarySearch.call(this);

      }
    }
});


/* Handle Primary Search */
function processPrimarySearch() {
    var obj = $(this),
        search_id = obj.attr('id'), // e.g. #field1
        search_value = obj.val(); // e.g. '123-456'

    /* Wait until at least 3 characters have been entered, or user has cleared the input */
    if (search_value.length >= 3 || (!search_value) ) {
        myTable.draw();
    }   
}

每当发出新的ajax请求时,我如何才能将其终止,以免它们以这种方式排队?我已经阅读了如何停止DataTables实例已经启动的所有当前正在进行的Ajax查询?但是该解决方案是针对较旧版本的DataTables的,并且可接受的答案似乎对我不起作用。


阅读 255

收藏
2020-07-26

共1个答案

小编典典

如果您使用的是DataTable默认提供的搜索字段,则需要使用searchDelay选项。默认情况下,使用服务器端处理时,它设置为400ms。但是,您有"searching": false,因此您不能在用例中使用此选项。

您提供自己的自定义input元素以执行搜索。这是对DataTables的完全有效的使用。
但是,您应该做的是在创建请求后不要中止请求,而是首先要防止创建无关的请求。
您应该做的是myTable.draw()取消对的呼叫。在下面的示例中,我使用的是Lodash的debounce。如果需要,可以使用另一个库中的实现。在以下示例中,我还修改了事件处理,以检查两次击键之间输入字段的值是否实际发生了变化。您正在检查选项卡,但这只是冰山一角。使用箭头键也会生成keyup事件。只要按下并释放Shift键,事件就会产生一个keyup。下面的代码通过检查自上次笔触以来该字段的值是否已更改来处理所有这些情况,如果没有更改,则忽略该事件。

我输入的速度足够快,如果在下面示例中显示的字段中输入“ I’m a little teapot”,我在控制台上只能看到一次“ drawing”。

// We create a new function that will debounce calls to the draw() function.

var debouncedDraw = _.debounce(function() {

  // myTable.draw();

  console.log("drawing");

}, 500);





var prev_value = undefined;



/* Handle Primary Search */

function processPrimarySearch() {

  var obj = $(this),

    search_id = obj.attr('id'), // e.g. #field1

    search_value = obj.val(); // e.g. '123-456'



  // There's been no change to the field, ignore.

  if (prev_value === search_value) {

    return;

  }

  prev_value = search_value;



  /* Wait until at least 3 characters have been entered, or user has cleared the input */

  if (search_value.length >= 3 || (!search_value)) {

    debouncedDraw();

  }

}



$('#primarySearch input[type="text"]').on("keyup", processPrimarySearch);


<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="primarySearch">

  <input type="text">

</div>

您在注释中询问是否应保留当DataTables启动新查询时中止由DataTables启动的任何先前Ajax查询的代码。我将其删除。我从未在我的应用程序中依赖过此类代码。(您提到了我的问题。是的,我确实在给出的答案中使用了代码,但这是拆卸的代码,它是测试套件的一部分,而不是应用程序代码。)从理论上讲,这似乎是一件好事。毕竟,新查询使旧查询过时了,那么为什么不放弃旧查询并保存一些工作呢?对?实际上,收益将是适度的,因为:

  1. 以人类与GUI交互的速度,abort()很有可能在发出呼叫时,Ajax请求将已经在网络上发出。(实际上,我进行了一些手动测试,确实,我的速度还不够快,无法阻止浏览器发送请求。)因此,即使您中止请求,服务器也将收到请求。

  2. 此外,abort()这并不意味着通知服务器该请求已被取消。因此,您将不会在服务器上保存工作。(在页面上搜索“服务器”将使您直接在人们谈论服务器是否被通知的问题以及如果您需要通知服务器已取消请求的情况下该怎么做。)

您可能节省了一些重绘时间,但这并不是我真正要担心的问题。

另一方面,中止这样的请求 可能会导致其他问题。
为了查看会发生什么,我修改了我的一个应用程序以中止旧的请求,然后整个程序立即被炸毁。中止的请求与我的设置方式搭配不好DataTables。我不知道到底是什么引起了问题。也许我只是在使用正确的设置来使其蓬勃发展。或者我使用的插件不喜欢中止的请求。无论如何,中止请求都可能导致问题。

2020-07-26