如何在页面加载时从表中加载一定数量的行,并且仅在用户加载它们时才加载更多行?
Posted
技术标签:
【中文标题】如何在页面加载时从表中加载一定数量的行,并且仅在用户加载它们时才加载更多行?【英文标题】:How can i load a set number of rows from a table on pageload and only load further rows when the user loads them? 【发布时间】:2020-07-03 04:57:16 【问题描述】:我有一个使用 DataTables 的表格,它包含大量行,因此这会导致页面加载非常缓慢,因为我假设浏览器会等到表格填满后再显示页面。
我只想加载表格的一页(10 行),并且只在用户浏览表格时显示更多数据,显示加载标志也很好。
我研究并听说了一个名为“deferRender”的 DataTables 函数,它应该可以满足我的需求,但我无法让它与我的表一起使用。
我的表格有 8 列 + html 是使用 php 生成的,它从文本文件中的数据构建表格:
<?php
$tdcount = 1; $numtd = 8; // number of cells per row
$str = "<table id=\"table1\" class=\"table1 table table-striped table-bordered\">
<thead>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
</thead>
<tbody>
";
$f = fopen("tabledata.txt", "r");
if ( $f === FALSE )
exit;
while (!feof($f))
$arrM = explode(",",fgets($f));
$row = current ( $arrM );
if ($tdcount == 1)
$str .= "<tr>"; $str .= "<td>$row </td>";
if ($tdcount == $numtd)
$str .= "</tr>";
$tdcount = 1;
else
$tdcount++;
if ($tdcount!= 1)
while ($tdcount <= $numtd)
$str .= "<td> </td>"; $tdcount++;
$str .= "</tr>";
$str .= "</tbody></table>";
echo $str;
然后我用下面的代码把它变成一个数据表:
<script>
$(document).ready(function()
$('#table1').basictable(
forceResponsive: false
);
$('#table1').DataTable( "order": [[ 0, "desc" ]] );
);
</script>
我已阅读此处的说明:https://datatables.net/examples/server_side/defer_loading.html 并且知道我需要向 JS 添加参数:
"processing": true,
"serverSide": true,
"ajax": "scripts/server_processing.php",
"deferLoading": 57
并使用 server_processing 脚本,但是该示例仅显示如何在连接到数据库时使用它,而不是在使用 php 从文本文件加载数据时使用它。
我怎样才能做到这一点?
【问题讨论】:
您的数据是存储在数据库中还是存储在文件中有些偶然 - 您需要实现以支持 DataTables 的核心服务器端处理大致相同。查看从 DataTables 自动传递到您的服务器的数据结构(在 Sent Parameters 部分中描述)。并查看您需要填充并传递回 DataTables 作为响应的数据结构(在Returned Data 部分中描述)。 只是补充一点:“延迟加载”是一种额外的方式来优化您的服务器端处理 - 但它不是服务器端处理工作方式的核心。如果我的笔记没有帮助,我可以提供更长的答案 - 但请查看上面的链接,以及最简单的服务器端案例的数据结构。这应该有助于为您指明正确的方向。如果我没有抓住重点,当然可以告诉我! 谢谢,这确实有点帮助,但是如果你能为我的问题提供一个很好的详细解决方案,我仍然对如何做到这一点感到困惑@andrewjames 【参考方案1】:这将纯粹关注“服务器端”解决方案的 DataTables 方面。如何编写支持它所需的服务器端逻辑超出了此答案的范围。但我希望这些笔记至少能阐明这种逻辑需要是什么,以及如何处理它。
假设
假设您有一个文本文件,其中包含 1,000 行这样的数据(或一百万行 - 但太多行无法同时发送到浏览器和 DataTables)。文本文件是一个简单的管道分隔文件,包含三个字段:
id|name|description
1|widget_1|This is a description for widget 1
2|widget_2|This is a description for widget 2
3|widget_3|This is a description for widget 3
...
1000|widget_1000|This is a description for widget 1000
您希望使用服务器端处理一次将 10 个项目发送到 DataTables。
您的数据映射到一个简单的 JSON 结构,如下所示 - 一个对象数组(每个对象是一个记录):
[
"id": 1,
"name": "widget_1",
"description": "This is a description for widget 1"
,
"id": 2,
"name": "widget_2",
"description": "This is a description for widget 2"
,
... // more records...
]
数据表定义
您的数据表定义看起来像这样 - 在这个阶段故意非常简单:
<body>
<div style="margin: 20px;">
<table id="demo" class="display dataTable cell-border" style="width:100%">
</table>
</div>
<script type="text/javascript">
$(document).ready(function()
$('#demo').DataTable(
serverSide: true,
ajax:
url: 'http://localhost:7000/data',
type: 'POST'
,
columns: [
title: 'ID',
data: 'id' ,
title: 'Name',
data: 'name' ,
title: 'Description',
data: 'description'
]
);
);
</script>
</body>
初始响应
当网页首次显示时,它会向 URL (http://localhost:7000/data) 发送一个初始 POST 请求,并期望从 Web 服务器接收 JSON 响应,其中包含要显示的数据。
由于 DataTables 使用的是serverSide: true
,DataTables 将期望 JSON 具有特定的结构,如 here 所述。
具体来说,服务器必须将所有必填字段(draw
、recordsTotal
、recordsFiltered
和 data
)添加到它发送到 DataTables 的 JSON 中。
在我们的例子中,它看起来像这样 - 请注意,它只是我们之前提到的 JSON 结构,添加了一些额外的元数据字段:
"draw": 1,
"recordsTotal": 1000,
"recordsFiltered": 1000,
"data": [
"id": 1,
"name": "widget_1",
"description": "This is a description for widget 1"
,
"id": 2,
"name": "widget_2",
"description": "This is a description for widget 2"
,
"id": 3,
"name": "widget_3",
"description": "This is a description for widget 3"
,
"id": 4,
"name": "widget_4",
"description": "This is a description for widget 4"
,
"id": 5,
"name": "widget_5",
"description": "This is a description for widget 5"
,
"id": 6,
"name": "widget_6",
"description": "This is a description for widget 6"
,
"id": 7,
"name": "widget_7",
"description": "This is a description for widget 7"
,
"id": 8,
"name": "widget_8",
"description": "This is a description for widget 8"
,
"id": 9,
"name": "widget_9",
"description": "This is a description for widget 9"
,
"id": 10,
"name": "widget_10",
"description": "This is a description for widget 10"
]
构建这个 JSON 是服务器的责任——服务器数据集的前 10 条记录。服务器还告诉 DataTables 它总共有 1,000 条记录,并且它还没有过滤掉任何数据 - 因此过滤后总共有 1,000 条记录。
DataTables 需要所有这些信息,因此它知道要显示多少个分页按钮,以及要显示哪些分页数据。
请注意,完成所有这些工作完全是服务器的责任——这就是为什么它被称为“服务器端”处理。
客户端(浏览器)只有 10 条记录要呈现 - 所以这很快就会发生。
(我刚刚注意到屏幕截图提到了“500 条记录”——这是我的服务器端代码中的一个错误——没有过滤器,所以我需要修复它)。
后续请求
当用户单击页面导航按钮(例如页面“4”)时,会触发从 DataTables 到服务器的新请求。 DataTables 使用here 描述的字段自动构建此请求。
请求作为表单数据发送。
在我们的示例中,请求如下所示:
"Form data":
"draw": "5",
"columns[0][data]": "id",
"columns[0][name]": "",
"columns[0][searchable]": "true",
"columns[0][orderable]": "true",
"columns[0][search][value]": "",
"columns[0][search][regex]": "false",
"columns[1][data]": "name",
"columns[1][name]": "",
"columns[1][searchable]": "true",
"columns[1][orderable]": "true",
"columns[1][search][value]": "",
"columns[1][search][regex]": "false",
"columns[2][data]": "description",
"columns[2][name]": "",
"columns[2][searchable]": "true",
"columns[2][orderable]": "true",
"columns[2][search][value]": "",
"columns[2][search][regex]": "false",
"order[0][column]": "1",
"order[0][dir]": "asc",
"start": "30",
"length": "10",
"search[value]": "",
"search[regex]": "false"
这些字段告诉服务器它需要知道的一切,因此它可以准备正确的响应。
在我们的例子中,最重要的字段是:
"start": "30",
"length": "10"
从第 30 行开始,提供 10 条记录。
同样,服务器有责任准备一个准确反映所请求数据的 JSON 响应。
在我们的例子中,这意味着服务器需要有逻辑来读取文本文件到正确的起点(数据行 31 - 记住偏移量从零开始),总共 10 行(第 31 到 40 行)。
上述来自 DataTables 的请求中的其他字段描述了如何对数据进行排序和过滤。在我们的例子中,没有过滤器"search[value]": "",
- 数据将按第一列升序排序。
最后说明
我故意不描述以下内容:
1) 您的服务器端代码如何处理它发送回 DataTables 的 JSON 响应的创建;
2) 您的服务器端代码如何解析从 DataTables 接收的表单请求。
这完全取决于您的服务器端技术是什么。数据表不在乎。它只是传递 JSON 消息 - 它与服务器端实现分离 - 应该如此。
关于here 中描述的“延迟渲染”选项,如果您觉得需要,可以选择添加它。但我建议先让一个更基本的服务器端实现工作。
【讨论】:
以上是关于如何在页面加载时从表中加载一定数量的行,并且仅在用户加载它们时才加载更多行?的主要内容,如果未能解决你的问题,请参考以下文章