在回调中使用ajax,其中父进程本身依赖于ajax调用

And*_*ndy 5 javascript ajax jquery

我正在使用一个使用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;
        }
    },
    // ... 
});
Run Code Online (Sandbox Code Playgroud)

DataTables提供了一个回调,称为rowCallback(https://datatables.net/reference/option/rowCallback),它允许在绘制表格对表格行进行后处理.这里的关键是它是 ajax请求之后/get-substances.json ; 该表必须填充数据,因为此回调用于在该点处操作其中的数据.

rowCallback我提供行ID的数组在我的表-也就是编号的对应于<tr>元素里面#substancesTable-我去拓展这些行.我可以通过在行ID的数组中进行硬编码来手动执行此操作,例如

 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');
       }
 });
Run Code Online (Sandbox Code Playgroud)

我已经硬编码的数组意味着在填充表格扩展第4行和第7行,这相当于用户点击它们.

我遇到的问题是我不想硬编码数组.应用程序存储相当于var indexRedis(缓存)的含义,这意味着即使用户离开页面,我们也可以轻松获取数据.所以我添加了第二个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);
});
Run Code Online (Sandbox Code Playgroud)

我知道ajax的本质意味着我的代码是异步的.在某些情况下,上面显示的ajax请求将在绘制DataTable之前完成,因此我在呈现表之前出现console.log(activeRows),在其他情况下,它会在之后发生.

制作第二个ajax请求的正确方法是什么,以便可以使用它的值来代替硬编码数组?我很欣赏我需要将响应转换为数组(因为它在console.log语句中仍然是JSON ).但是我的问题集中在哪里放置这些代码,以便可以在内部可靠地使用rowCallback

我已阅读如何从异步调用返回响应?并了解异步性质.我无法弄清楚如何构造它以在已经是ajax请求的一部分的回调中使用.

任何意见,将不胜感激.

该应用程序使用DataTables版本1.10.16和jquery 3.2.1

Sal*_* CJ 3

您实际上可以使用该ajax选项来:

  1. 发出第一个 AJAX 请求来检索活动行。

  2. 检索到活动行后,发出第二个 AJAX 请求来检索表数据。

示例:(请参阅此处的完整代码和演示)

var activeRows = [];

function getActiveRows() {
  return $.ajax({
    url: '/view-substance/get-active-rows',
    type: 'POST',
    dataType: 'json'
    ...
  }).done(function(data){
    activeRows = data;
    console.log(activeRows);
  });
}

function getTableData(data, callback) {
  return $.ajax({
    url: '/get-substances.json',
    type: 'POST',
    dataType: 'json',
    'data': data // must send the `data`, but can be extended using $.extend()
    ...
  }).done(callback); // and call callback() once we've retrieved the table data
}

$('#example').dataTable({
  ajax: function(data, callback){
    getActiveRows().always(function(){
      getTableData(data, callback);
    });
  },
  rowCallback: function(row, data){
    ...
  }
});
Run Code Online (Sandbox Code Playgroud)

更新

在上面的示例中,我将 AJAX 调用分为两个不同的函数,主要是为了避免在ajax调用$('#example').dataTable(). 否则代码将如下所示:

var activeRows = [];

$('#example').dataTable({
  ajax: function(data, callback){
    // 1. Retrieve the active rows.
    $.ajax({
      url: '/view-substance/get-active-rows',
      type: 'POST',
      dataType: 'json'
      ...
    }).done(function(res){
      activeRows = res;
      console.log(activeRows);
    }).always(function(){
      // 2. Retrieve the table data.
      $.ajax({
        url: '/get-substances.json',
        type: 'POST',
        dataType: 'json',
        'data': data // must send the `data`, but can be extended using $.extend()
        ...
      }).done(callback); // and call callback() once we've retrieved the table data
    });
  },
  rowCallback: function(row, data){
    ...
  }
});
Run Code Online (Sandbox Code Playgroud)

我使用了.always()这样的方式,以便在检索活动行失败的情况下仍然可以检索表数据。