【问题标题】:Datatables - Return Column as HTML <td> Element数据表 - 将列作为 HTML <td> 元素返回
【发布时间】:2017-12-27 20:54:28
【问题描述】:

我在将一些客户端数据表逻辑迁移到服务器端时遇到了一些困难。

我当前的问题是,对于 Datatables,如果您想对大量数据(20,000 多行)进行分页,我首先需要加载 Controller 中的所有行,然后将它们传递给视图:

$records = \App\Records::get();

return view("example.datatables")->with(["records" => $records]);

接下来,这需要大约 2 分钟的等待时间,然后才能加载所有内容,Datatables 会将记录分页为 500 页:

$("#table").DataTable({
  paging: true,
  pageLength: 500,
  ...
});

我已将 Datatables 声明更改为通过 ajax 处理服务器端处理,如下所示:

$("#table").DataTable({
  processing: true,
  serverSide: true,
  ajax: {
    url: "...",
    type: "GET"
  }, paging: true,
  pageLength: 500,
  ...
});

按照我的意愿让它工作已经很顺利了,但问题是 Datatables 覆盖或忽略了我从ajax 请求发回的内容:

$columnData = [];
foreach($recordsFromDatabase AS $record){
  $columnDataObject = [];

  $columnDataObject[0] = '<td class="myClass" data-property="myProperty"><input type="text" name="customInput[]"/></td>'

  ...

  $columnData[] = $columnDataObject;
}

return response()->json([
  "draw" => (int)$request->input("draw"),
  "recordsTotal" => $totalRecords,
  "recordsFiltered" => $totalFilteredRecords,
  "data" => $columnData,
  "error" => null
]);

基本上,我发回的是一个包含datajson 响应,它是一个列数组,它们是&lt;td&gt; 元素,而不仅仅是一个普通值。所以&lt;td&gt;Value&lt;/td&gt; vs Value

Datatables 给人的错觉认为这是正常工作,但我最终得到了

<tr role="row" class="even">
  <td class="sorting_1"><input type="text" name="customInput[]"/></td>
  ...
</tr>
<tr role="row" class="odd">
  <td class="sorting_1"><input type="text" name="customInput[]"/></td>
  ...
</tr>

它正确地呈现了&lt;td&gt; 内部的&lt;input&gt;,但缺少class="myClass" data-property="myProperty",这破坏了我的表的扩展功能。

有什么方法可以告诉 Datatables 我发回的是有效的 &lt;td&gt; 元素,它需要做的就是添加一个 oddeven 类? (即便如此,我认为这只是为了造型)。

【问题讨论】:

  • 查找laravel分页laravel.com/docs/5.4/pagination
  • 这不是 Laravel 分页的问题,也不是一般的分页问题。
  • 当您可以使用 laravel 分页类完成所有这些操作时,您不需要数据表,并且使用分页执行此操作通常会加快进程,因为您将处理 x 块而不是 20,000
  • 我知道,相信我,我不想仅仅因为这个原因而使用 Datatables,但由于客户的要求,我被锁定了。此外,这是一个非常小众的问题,所以即使 Laravel 分页会产生奇迹,但它对我来说不是一个选择。为这个建议干杯。

标签: php jquery ajax laravel datatables


【解决方案1】:

您错误地使用了 jQuery DataTables。

您不应将&lt;td&gt; 元素作为您的数据发送。使用columns.render 选项为您的单元格生成内容和/或使用columns.createdCell 选项添加属性到&lt;td&gt; 元素。

例如:

$('#example').DataTable( {
  "columnDefs": [ {
    "targets": 3,
    "createdCell": function (td, cellData, rowData, row, col) {
      $(td)
        .attr('data-property', rowData['myCustomProperty'])
        .addClass(rowData['myClass']);
    }
  } ]
} );

对于 Laravel,使用优秀的 Laravel DataTables 包以在服务器端处理模式下正确显示表格。

【讨论】:

  • 我认为我用错了,发回html,谢谢你的澄清。唯一的问题是我需要发回的这些data-* 属性必须在服务器端生成;处理该问题的返回数据是什么样的?
  • 例如,在第一个&lt;td&gt;,我需要data-record-id="'.$record-&gt;id.'"&gt;...&lt;/td&gt;,所以它要么需要是服务器端的属性,要么以某种方式通过response传递给JS
  • @TimLewis,您可以在回复中发送 ID。您不必为了检索 ID 分配 data- 属性,使用 row().data() API 方法随时可以获得完整的行数据,您可以将 tr 元素作为参数传递给 row() 函数。
【解决方案2】:

所以我最终仍然通过我的响应发送 HTML,并使用数据表的 createdRow 回调,我能够将 HTML 解析为本地 DOM 元素,检查它们的类和属性,并根据需要将它们分配给行/列:

createdRow: function(row, data, rowIndex) {
  $.each($("td", row), function (colIndex) {
    var elementFromData = $.parseHTML(data[colIndex]);
    var element = elementFromData[0];

    var elementClass = $(element).attr("class");
    if(typeof elementClass !== undefined){
      $(this).addClass(elementClass);
    }

    var attributes = [
      {
        label: "data-id",
        value: $(element).attr("data-id")
      }, ...
    ];

    for(var i = 0; i < attributes.length; i++){
      var attribute = attributes[i];

      if(typeof attribute.value !== undefined){
        $(this).attr(attribute.label, attribute.value);
      }
    }
  });
}, ...

这可能不是最漂亮的解决方案,而且我知道从我的 AJAX 请求返回 HTML 效率低下,但由于时间限制,这是我能想到的最佳解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-15
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 2010-10-26
    • 2022-01-19
    • 2020-12-29
    • 2021-07-03
    相关资源
    最近更新 更多