消除DataTables.net中的重复行

时间:2018-12-17 21:23:26

标签: datatables

上下文:我有一个Web工作者,它通过Websocket从后端“订阅”数据更新,然后将其发布到通过DataTables.net呈现的视图中。为了提高效率,添加的数据作为部分记录(即,仅一行)。

由于数据已从DataTable解耦(即,它没有使用Ajax API;它基本上是JavaScript源),所以我不能只添加行并呈现表。如果触发了同一行的两次按下,我将得到重复的行。

所以,我整理了一个小插件:

$.fn.dataTable.Api.register('deDupe', function (dataSet, idColumn) {
  idColumn = idColumn || 0;
  var columnData = this.columns().data()[idColumn];

  for(var i=0; i < dataSet.length; i++) {
    var thisId = dataSet[i].id;
    var matchedIndex = columnData.indexOf(thisId);
    if(matchedIndex > -1) {
      var matchedRow = $(this.rows().nodes()[matchedIndex]);
      this.row(matchedRow).remove();
    }
  }

  // return "this" for chaining
  return this;
});

(不要嘲笑我在老式的“ for”循环中获得安慰!)

然后在使用中,我这样做:

myTable.deDupe(dataSet).rows.add(dataSet).draw();

接收数据然后更新表的方法已经有输入行,该行包含在“ dataSet”中,然后我为该列传递一个COLUMN索引,该索引旨在包含用于重复数据删除的唯一ID目的。请注意,在代码执行中,不是删除传入的重复项,而是删除上一行,然后添加传入的行。在某些情况下,该行包含更新的数据,而我实际上只关心在ID级别进行重复数据删除,而不是在内容级别进行重复数据删除……始终只是盲目地使用最新数据。

那么几个问题:

  1. 是否有更好的方法?我很想看到一种核心选择,但我没有遇到。似乎是相对常见的功能。我在这里疯了,重新发明轮子吗? (换句话说,是一个初始化选项?)

  2. 在条件检查中是否存在匹配项时,您会看到以下行:var matchedRow = $(this.rows().nodes()[matchedIndex]);这让我感到古怪,但是我无法理解其他识别要使用的行的方法在.remove()链中。在我的脑海中,我已经知道该行的索引,因此我认为类似matchedRow = this.rows(matchedIndex)的方法可以工作,但是找不到或类似的方法。因此,我不仅要深入研究rows().nodes(),而且还要将整个内容包装在jQuery中,然后再传递给.row(matchedRow)'。似乎我已经应该可以直接访问某些东西了,所以嵌套和包裹得太紧了。

别误会我的意思;代码“有效”并修复它可能是微观优化。但这使我感到非常困惑,并给了我一些代码味道,为了维护开发人员,我希望避免这种情况。

1 个答案:

答案 0 :(得分:1)

如您所说,这可能是微优化,但是一个选择可能是选择所有行并将它们全部删除。

$.fn.dataTable.Api.register('deDupe', function (dataSet, idColumn) {

  idColumn = idColumn || 0;

  // Get the possible dataSet ids into an array for easier lookup
  var dsIds = dataSet.map( (d) => d.id );

  // Use a function in the rows() API to obtain all rows with
  // a value in the idColumn that matches one of the incoming
  // ids on the dataSet
  var matchedRows = this.rows( (i,r) => dsIds.indexOf(r[idColumn]) > -1 );

  // Remove all of the rows at once (this could be chained to the selector above)
  matchedRows.remove();

  // return "this" for chaining
  return this;
});

请参见row-selector:Function reference