如何在页面加载时从表加载一定数量的行,并且仅在用户加载它们时才加载更多行? [英] How can i load a set number of rows from a table on pageload and only load further rows when the user loads them?
问题描述
我有一个使用DataTables的表,它包含大量行,因此这导致页面加载非常缓慢,因为我假设浏览器在显示页面之前一直等到表被填满.
I have a table using DataTables , it contains a large number of rows and so this causes the page to load very slowly as i assume the browser waits till the table is filled before displaying the page.
我只想加载表格的一页(10行),并且仅当用户浏览表格时才显示更多数据,这表明加载标志也很好.
I would like to only load one page of the table (10 rows), and only show further data when the user browses through the table, showing a loading sign would be great too.
我已经研究并听说了一个名为"deferRender"的DataTables函数,该函数本来可以满足我的需要,但我无法使其与我的表一起使用.
I have researched and heard of a DataTables function called 'deferRender' which is supposed to do what i need, but i can't get it to work with my table.
我的表有8列,并且html是使用PHP生成的,该PHP使用文本文件中的数据构建表:
My table has 8 columns + the html is generated using PHP that builds the table from data in a text file:
<?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;
然后我使用以下代码将其转换为数据表:
I then use the following code to turn it into a datatable:
<script>
$(document).ready(function() {
$('#table1').basictable({
forceResponsive: false
});
$('#table1').DataTable( { "order": [[ 0, "desc" ]] } );
});
</script>
我已在此处阅读说明: https://datatables.net/examples/server_side/defer_loading.html 并且知道我需要向JS添加参数:
I have read the instructions here: https://datatables.net/examples/server_side/defer_loading.html and know i need to add parameters to the JS:
"processing": true,
"serverSide": true,
"ajax": "scripts/server_processing.php",
"deferLoading": 57
并使用server_processing脚本,但是该示例仅显示了如何在连接到数据库时使用它,而不是在使用php从文本文件中加载数据时使用.
and use a server_processing script, however the example only shows how to use it when connecting to a DB, and not when the data is loaded from a text file with php.
我该如何实现?
推荐答案
这将纯粹专注于服务器端"解决方案的DataTables方面.如何编写支持该逻辑所需的服务器端逻辑超出了此答案的范围.但我希望这些说明至少能阐明该逻辑的含义以及如何实现它.
This will focus purely on the DataTables aspects of a "server-side" solution. How you write the server-side logic needed to support it is out of scope for this answer. But I hope these notes will at leasst clarify what that logic needs to be, and how you can approach it.
假设您有一个文本文件,其中包含这样的1,000行数据(或一百万行,但是一次发送到浏览器和DataTables的行太多).文本文件是一个简单的管道分隔文件,具有三个字段:
Assume you have a text file containing 1,000 rows of data like this (or a million - but too many rows to send to the browser and to DataTables, all at once). The text file is a simple pipe-delimited file, with three fields:
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.
You want to send 10 items at a time to DataTables, using server-side processing.
您的数据映射到一个简单的JSON结构,像这样-对象数组(每个对象是一个记录):
Your data maps to a simple JSON structure, like this - an array of objects (each object is one record):
[
{
"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...
]
数据表定义
您的数据表定义如下所示-在现阶段,它非常简单:
The DataTable Definition
Your datatable definition looks like this - it is deliberately very simple, at this stage:
<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发送初始POST请求( http://localhost: 7000/data ),它将期望从Web服务器接收到JSON响应,其中包含要显示的数据.
Initial Response
When the web page is first displayed, it will send an initial POST request to the URL (http://localhost:7000/data), and it will expect to receive a JSON response from the web server, containing the data to be displayed.
由于DataTables使用的是serverSide: true
,因此DataTables将期望JSON具有特定的结构,如
Because DataTables is using serverSide: true
, DataTables will expect the JSON to have a specific structure, as described here.
具体来说,服务器必须将所有必填字段(draw
,recordsTotal
,recordsFiltered
和data
)添加到它发送到DataTables的JSON中.
Specifically, the server has to add all of the mandatory fields (draw
, recordsTotal
, recordsFiltered
, and data
) to the JSON it sends to DataTables.
在我们的例子中,它看起来像这样-请注意,这只是我们前面提到的JSON结构,并添加了一些额外的元数据字段:
In our case it would look like this - note that it is just our previously mentioned JSON structure, with a few extra metadata fields added:
{
"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,它总共有1000条记录,并且尚未过滤掉任何数据(因此),因此,过滤后也总共有1000条记录.
It is the server's responsibility to build this JSON - the first 10 records of the server's data set. The server also tells DataTables that it has a total of 1,000 records, and that it has not filtered out any data (yet) - hence there are also a total of 1,000 records after filtering.
DataTables需要所有这些信息,因此它知道要显示多少个分页按钮,以及要显示什么分页数据.
DataTables needs all of this information, so it knows how many pagination buttons to display, and what pagination data to show.
请注意,完成所有这些工作完全是服务器的责任-这就是为什么将其称为服务器端"处理.
Note that it is entirely the server's responsibility to do all this work - that's why it's called "server-side" processing.
客户端(浏览器)只有10条记录可呈现-这样很快就可以完成.
The client (browser) only has 10 records to render - so that happens quickly.
(我只是注意到屏幕截图提到"500条记录"-这是我的服务器端代码中的一个错误-没有过滤器,因此我需要对其进行修复.)
(I just noticed that the screenshot mentions "500 records" - that's a mistake in my server-side code - there is no filter, so I need to fix that).
当用户单击页面导航按钮(例如页面"4")时,将触发从DataTables向服务器的新请求. DataTables使用此处所述的字段自动构建此请求.
When a user clicks on a page navigation button (e.g. page "4"), that triggers a new request from DataTables to the server. DataTables builds this request automatically, using the fields described here.
请求作为表单数据发送.
The request is sent as form data.
在我们的示例中,请求如下所示:
In our example, the request looks like this:
"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"
}
这些字段告诉服务器它需要知道的所有信息,以便它可以准备正确的响应.
These fields tell the server everything it needs to know, so it can prepare the correct response.
在我们的案例中,最重要的字段如下:
In our case the most important fields are these:
"start": "30",
"length": "10"
从第30行开始,并提供10条记录.
Start at row 30, and provide 10 records.
再次,服务器有责任准备一个JSON响应,以准确反映所请求的数据.
It is, again, the server's responsibility to prepare a JSON response which accurately reflects the requested data.
在我们的情况下,这意味着服务器需要逻辑来读取文本文件至正确的起点(数据行31-记住偏移量从零开始),总共10行(行31至40).
In our case this means the server needs to have logic to read through the text file to the correct starting point (data row 31 - remember the offset starts at zero), and 10 rows in total (rows 31 through 40).
以上来自DataTables的请求中的其他字段描述了如何对数据进行排序和过滤.在我们的示例中,没有过滤器"search[value]": "",
-数据将按升序在第一列中进行排序.
Other fields in the above request from DataTables describe how the data is to be sorted, and filtered. In our case there is no filter "search[value]": "",
- and the data is to be sorted by the first column in ascending order.
我故意没有描述以下内容:
I have deliberately not described the following:
1)服务器端代码如何处理发送回DataTables的JSON响应的创建;
1) How your server-side code handles the creation of the JSON responses it sends back to DataTables;
2)服务器端代码如何解析从DataTables接收到的表单请求.
2) How your server-side code parses the form requests it receives from DataTables.
这完全取决于您的服务器端技术. DataTables不在乎.它只是传递JSON消息-它应从服务器端实现中分离出来-应当如此.
That all depends entirely on what your server-side technology is. DataTables doesn't care. It's just passing JSON messages - it is decoupled from the server-side implementation - as it should be.
关于此处中所述的延迟渲染"选项,您可以选择该增强功能如果您认为需要添加.但是我建议先让一个更基本的服务器端实现开始工作.
Regarding the "defer render" option described here, that is an enhancement you may choose to add if you feel you need it. But I would recommend getting a more basic server-side implementation working first.
这篇关于如何在页面加载时从表加载一定数量的行,并且仅在用户加载它们时才加载更多行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!