Я работаю с приложением, которое использует DataTables для создания таблицы HTML, которая заполняется данными из запроса ajax.
Это довольно просто:
var substancesTable = $('#substancesTable').DataTable({
"processing": true,
"serverSide": true,
"searching": false,
"ajax": {
"url": "/get-substances.json",
"method": "POST",
"cache": false,
"dataSrc": function (json) {
// Update non-Datatables UI elements and perform other functions based on the ajax response
$('#numSubstances').html(json.recordsTotal);
drawOptionsButton(json.isFiltering);
// Must return data for DataTables to work
return json.data;
}
},
// ...
});
Существует обратный вызов, который предоставляет DataTables, который называется rowCallback
(https://datatables.net/reference/option/rowCallback), который позволяет постобработать строки таблицы после таблицы нарисованной. Ключевым моментом здесь является то, что она после ajax-запрос к /get-substances.json
; таблица должна быть заполнена данными, потому что этот обратный вызов используется для манипулирования данными внутри нее в этот момент.
В пределах rowCallback
я предоставляю массив идентификаторов строк в моей таблице - то есть идентификаторы, которые соответствуют <tr>
элементам внутри #substancesTable
- и я продолжаю расширять эти строки. Я могу сделать это вручную путем жесткого кодирования в массиве идентификаторов строк, например,
var substancesTable = $('#substancesTable').DataTable({
// ...
"rowCallback": function(row) {
var id = $(row).find('td:first').text();
var index = $.inArray(id, ['4', '7']); // hardcoded array
if (index !== -1) {
var tr = $(row).closest('tr');
var row = substancesTable.row( tr );
row.child.show();
tr.addClass('active');
}
});
Массив, который я жестко закодировал, означает, что строки 4 и 7 расширяются после заполнения таблицы, что эквивалентно нажатию пользователем на них.
Проблема в том, что я не хочу жестко кодировать массив. Приложение хранит эквивалент var index
в Redis (кеш), что означает, что мы можем легко получить данные, даже если пользователь покидает страницу. Поэтому я добавил второй запрос ajax (за пределами блока var substancesTable...
) для получения данных Redis. Это делает ajax-запрос для заполнения массива, activeRows
:
var activeRows = [];
$.ajax({
url: '/view-substance/get-active-rows',
method: 'post',
cache: false,
}).done(function(data) {
activeRows = data;
console.log(activeRows);
});
Я понимаю, что природа ajax означает, что мой код асинхронный. В некоторых случаях запрос ajax, показанный выше, завершится до отрисовки DataTable, поэтому я получаю console.log (activeRows), появляющийся до визуализации таблицы, а в других случаях это происходит позже.
Как правильно сделать второй запрос ajax таким, чтобы его значения могли использоваться вместо жестко закодированного массива? Я ценю, что мне нужно будет преобразовать ответ в массив (так как это все еще JSON в операторе console.log
). Но мой вопрос сосредоточен на том, где разместить этот код так, чтобы он мог надежно использоваться внутри rowCallback
?
Я прочитал Как мне вернуть ответ от асинхронного вызова? и понять, что такое асинхронная природа. Я не могу понять, как структурировать это для использования в обратном вызове, который уже является частью запроса AJAX.
Любой совет будет принят.
Приложение использует DataTables версии 1.10.16 и jquery 3.2.1