如何在页面加载时从表中加载一定数量的行,并仅在用户加载时加载更多行?

IT技术 javascript php ajax datatables
2021-03-12 22:00:19

我有一个使用 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>&nbsp;</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 从文本文件加载数据时使用它。

我怎样才能做到这一点?

1个回答

这将完全集中在“服务器端”解决方案的 DataTables 方面。您如何编写支持它所需的服务器端逻辑超出了本答案的范围。但我希望这些笔记至少能阐明逻辑需要是什么,以及如何处理它。

假设

假设您有一个文本文件,其中包含 1,000 行这样的数据(或一百万行 - 但太多行无法一次性发送到浏览器和数据表)。文本文件是一个简单的以竖线分隔的文件,包含三个字段:

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

您希望使用服务器端处理一次向 DataTables 发送 10 个项目。

您的数据映射到一个简单的 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>

初步react

当网页第一次显示时,它会向 URL ( http://localhost:7000/data )发送一个初始 POST 请求,它会期望从 Web 服务器收到一个 JSON 响应,其中包含要显示的数据.

由于数据表使用serverSide: true,数据表将期望JSON有一个特定的结构,描述在这里

具体而言,服务器必须添加所有强制字段(的drawrecordsTotalrecordsFiltered,和data),以将其发送到数据表的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 使用此处描述的字段自动构建此请求

请求作为表单数据发送。

在我们的示例中,请求如下所示:

"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 消息——它应该与服务器端实现分离。

关于此处描述的“延迟渲染”选项,如果您觉得需要,您可以选择添加该选项。但我建议先让更基本的服务器端实现工作。