Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
750 views
in Technique[技术] by (71.8m points)

jquery - DataTables - kill ajax requests when a new one has started

I'm using DataTables 1.10.15 in Server Side mode.

I'm passing the contents of a form to a PHP script via ajax in order for it to search a database:

 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",
    }
 });

I have some other js which checks for at least 3 characters entered into a field before firing the ajax request to /getData.php.

This means - after 3 characters have been entered - that an ajax request is made each time a key is pressed, so there can be a queue of ajax requests.

$('#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();
    }   
}

How can I kill off the previous ajax requests whenever a new one is made, so that they don't queue in this way? I've read How can I stop all the currently ongoing Ajax queries that DataTables instance have started? but the solution is for an older version of DataTables and the accepted answer doesn't seem to work for me.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you were using the search field that DataTable offers by default, you'd want to use the searchDelay option. By default it is set to 400ms when you use server-side processing. However, you have "searching": false, therefore you cannot use this option for your use-case.

You provide your own custom input element to perform searches. This is a perfectly valid use of DataTables. However, what you should do is not abort requests after they are created but prevent the creation of extraneous requests in the first place. What you should do is debounce your calls to myTable.draw() In the example below I'm using Lodash's debounce. You could use an implementation from another library if you want. In the following example, I've also modified the event handling to check whether the input field value has actually changed between keystrokes. You were checking for tabs but that's only the tip of the iceberg. Using arrow keys will also generate keyup events. Event just pressing and releasing the shift key will generate a keyup. The code below takes care of all those situations by checking whether the value of the field has changed since the last stroke and just ignore the event if there has been no change.

I type fast enough that if I type "I'm a little teapot" in the field presented in the example below I'm seeing "drawing" on the console only once.

// 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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...