【问题标题】:Simple pagination in datatable using ajax without sending total count from server使用ajax在数据表中进行简单分页而不从服务器发送总数
【发布时间】:2025-12-16 21:35:02
【问题描述】:

我正在使用 DataTables 1.10.5。我的表通过 ajax 使用服务器端处理。

$('#' + id).dataTable({
  processing: true,
  serverSide: true,
  ajax: 'server-side-php-script-url',
  "pagingType": "simple_incremental_bootstrap"
});

如果我在服务器响应中发送“recordsTotal”,一切都会正常工作。但由于性能问题,我不想计算总条目。所以我尝试使用分页插件simple_incremental_bootstrap。但是它没有按预期工作。下一个按钮总是返回第一页本身。如果我在服务器响应中给出“recordsTotal”,这个插件将正常工作。我发现如果我们不给'recordsTotal',datatable发送给服务器端脚本的'start'参数总是0。所以我的服务器端脚本总是返回第一页。

根据this discussion,不计算总计数的服务器端处理是不可能的,因为“DataTables 使用传回给它的记录计数来处理分页控制”。建议的解决方法是“因此需要显示记录,但可以只传回一个静态数字(如 1'000'000 或其他),这会使 DataTables 认为有一百万行。如果此信息完全是伪造的,您可以隐藏信息元素!”

我想知道是否有人对此有解决方案。基本上我想在我的数据表中使用 ajax 进行简单的分页,而无需从服务器发送总数。

【问题讨论】:

标签: datatable pagination


【解决方案1】:

值得尝试的解决方法..

如果我们不从服务器发送 recordsTotal,分页将无法正常工作。如果我们发送一个高静态数字作为 recordsTotal,即使下一页没有数据,表格也会显示一个活动的 Next 按钮。

所以我最终找到了一个解决方案,它利用了在 ajax 脚本中接收到的两个参数 - 'start' 和 'length'。

如果当前页面中的行数小于“limit”,则下一页中没有数据。所以总计数将是“开始”+“当前页数”。这将禁用最后一页中的 Next 按钮。

如果当前页面中的行数等于或大于“limit”,则后续页面中的数据会更多。然后我将获取下一页的数据。如果下一页中至少有一行,则发送 recordsTotal 大于 'start + limit' 的内容。这将显示一个活动的下一步按钮。

示例代码:

$limit = require_param('length');
$offset = require_param('start');
$current_page_data = fn_to_calculate_data($limit, $offset); // in my case, mysqli result.
$data = “fetch data $current_page_data”;
$current_page_count = mysqli_num_rows($current_page_data);
if($current_page_count >= $limit) {
    $next_page_data  = fn_to_calculate_data($limit, $offset+$limit);
    $next_page_count = mysqli_num_rows($next_page_data);
    if($next_page_count >= $limit) {
        // Not the exact count, just indicate that we have more pages to show.
        $total_count = $offset+(2*$limit);
    } else {
        $total_count = $offset+$limit+$next_page_count;
    }
} else {
    $total_count = $offset+$current_page_count;
}
$filtered_count = $total_count;

send_json(array(
    'draw' => $params['draw'],
    'recordsTotal' => $total_count,
    'recordsFiltered' => $filtered_count,
    'data' => $data)
);

但是,此解决方案会增加服务器的一些负载,因为它还会计算下一页中的行数。无论如何,与计算总行数相比,这是一个很小的负载。

我们需要从表尾隐藏计数信息并使用简单的分页。

  dtOptions = {};
  dtOptions.pagingType = "simple";
  dtOptions.fnDrawCallback = function() {
    $('#'+table_id+"_info").hide();
  };
  $('#' + table_id).dataTable(dtOptions);

【讨论】: