2017-07-03 67 views
0

我在服務器端模式下使用DataTables 1.10.15。DataTables - 在新服務器啓動時拋出Ajax請求

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

我有檢查,至少3個字符輸入到其他一些JS在將ajax請求發送到/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請求,讓他們不以這種方式排隊?我已閱讀How can I stop all the currently ongoing Ajax queries that DataTables instance have started?,但解決方案適用於較舊版本的DataTable,並且接受的答案似乎對我無效。

+0

你不能。它已經在serverscript上處理了。 – davidkonrad

+0

我明白服務器正在處理腳本getData.php。但是可以停止Ajax請求(例如jquery中的'.abort()')。所以我想要做的是,如果說2個請求,已經對'getData.php'進行了處理,那麼它會殺死第一個請求,然後進入下一個請求。這樣就沒有腳本排隊了。該應用程序適用於每個按鍵,因此如果用戶輸入4個字符進行搜索,則不需要執行前3次搜索 - 它們可以在服務器處理它們之前關閉。我知道這是可能的,因爲它在我發佈的鏈接上,只是針對舊的數據表版本。 – Andy

+1

您可以設置一個標誌,比如'processing',然後避免在'processing'爲true時執行ajax-request,在ajax成功時,將'processing'設置爲false。 – davidkonrad

回答

1

如果您使用的是默認情況下DataTable提供的搜索字段,則您希望使用searchDelay option。默認情況下,當您使用服務器端處理時,它被設置爲400毫秒。但是,您有"searching": false,因此您不能在您的用例中使用此選項。

您提供自己的自定義input元素來執行搜索。這是對DataTables的完全有效的使用。 但是,你應該做的不是在創建它們之後放棄請求,而是首先防止創建無關的請求。你應該做的是反彈你的電話myTable.draw()在下面的例子中,我使用Lodash的debounce。如果需要,您可以使用另一個庫中的實現。在以下示例中,我還修改了事件處理,以檢查輸入字段值是否在擊鍵之間實際發生了更改。你正在檢查標籤,但這只是冰山一角。使用箭頭鍵也會生成keyup事件。只需按下並釋放Shift鍵的事件將生成一個keyup。下面的代碼通過檢查自上一次筆劃後字段的值是否發生了變化來處理所有這些情況,並在沒有變化的情況下忽略該事件。

我輸入的速度足夠快,如果我在下面的示例中顯示的字段中鍵入「我是一個小茶壺」,我只在控制檯上看到「繪圖」一次。

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


你問的評論,如果你應該讓你有這樣的中止任何先前的Ajax查詢的數據表啓動時數據表推出一個新的查詢代碼。我會刪除它。我從來沒有依賴過我的應用程序中的這種代碼。 (你提到了my question。是的,我在那裏給出的答案中使用了代碼,但是這是拆下的代碼,它是測試套件的一部分,而不是應用程序代碼。)理論上,這似乎是件好事。畢竟,新的查詢會使舊的查詢過時,爲什麼不排除舊的查詢並節省一些工作?對?

  1. 在人類與GUI交互的速度,很可能由abort()呼叫發出時,Ajax請求將已經被在網絡上發出了:在實踐中,由於收益將是適度的。(我實際上運行了一些手動測試,事實上,我從來沒有足夠快的速度阻止瀏覽器發送請求。)所以這意味着服務器即使中止它也會收到它。

  2. 此外,abort()並不意味着通知服務器請求已被取消。所以你不會在你的服務器上保存工作。查看this question的問題。 (在頁面上搜索「服務器」會使人們談論服務器是否得到通知的問題,以及如果需要通知服務器請求已被取消,應如何處理。)

您可能正在節省一些重繪時間,但這並不是我擔心的事情,除非它真的成爲問題。

另一方面,中止請求可能會導致其他問題。爲了看到會發生什麼,我修改了我的一個應用程序以中止舊請求,整個事情立即被轟炸。取消請求並不能很好地符合我設置DataTables的方式。我不知道究竟是什麼導致了這個問題。也許我正在使用正確的設置來讓它蓬勃發展。或者我正在使用一個不喜歡中止請求的插件。無論如何,放棄請求可能會導致問題。

+0

優秀。有很多事情我沒有考慮過 - 甚至從未聽說過反彈的功能。將更多地考慮這一點。非常感謝。 – Andy

+0

你也可以確認我是否可以刪除一些我添加的代碼來停止ajax請求排隊,這是'if(settings.jqXHR)settings.jqXHR.abort();' - 這是放在'.on('preXhr.dt' ,功能(e,設置,數據)' – Andy

+0

我的想法跑了太久的評論,所以我編輯了我的答案。 – Louis