如何使用 aoColumns 添加或注入列到 jQuery 数据表?

How to Add or Inject Columns to jQuery Datatable using aoColumns?

我目前正在尝试将数据列动态添加到 jQUery 数据table。

本质上,当用户单击 UI 组件(数据 Viz/Chart)时,它应该向数据 table 中注入一列新数据。

我试图通过将列信息推送到 datatable.fnSettings().aoColumns 然后重新呈现数据来做到这一点table.

但是我收到一个错误。

我的代码如下所示:

This is part of an extensive feature on a dashboard in which the tables are integrated with C3.js + DC.js + Crossfilter.JS

这是我的 HTML Table:

<table id="dc-data-table" class="list table table-striped table-bordered">
  <thead>
    <tr>
       <th>Name</th>
       <th>Date</th>
       <th>Age</th>
       <th>Gender</th>
    </tr>
  </thead>
</table>

下面是 Javascript,它在 DC 和 Crossfilter 方面呈现 table。

RefreshTable() 将重绘 table 如果用户使用带 Crossfilter 的 DC 图过滤数据集...本质上数据集发生变化然后

datatable.fnClearTable(); datatable.fnAddData(newdataset); datatable.fnDraw();

用于更新数据table。

var ndx = crossfilter(data);
var all = ndx.groupAll();

var tabledim = ndx.dimension(function(d){return d.name});

dc.dataCount(".dc-data-count")
  .dimension(ndx)
  .group(all);

  var datatable = $("#dc-data-table").dataTable({
      "bSort": true,
      "bInfo": false,
      "bAutoWidth": false,
      "bInfo": true,
      "bDeferRender": true,
      "aaData": tabledim.top(Infinity),
      "bDestroy": true,
      "aoColumns": [
            { "mData": "name",
              "mRender": function(client) {
                 var res = '<a href="/URL/To/Person/' + client + '/" target="_blank">' + client + '</a>';
            return res;}},
            { "mData": "date_call_rcvd",
              "mRender": function(d) {return dtFormat2(parseDate(d));}},
            { "mData": "age",
              "sDefaultContent": ""},
            { "mData": "gender",
              "sDefaultContent": ""}
          ],
          "aaSorting": [[0, "asc"]],
          "iDisplayLength": 25
  });

  function RefreshTable() {
      dc.events.trigger(function () {
          alldata = tabledim.top(Infinity);
          datatable.fnClearTable();
          datatable.fnAddData(alldata);
          datatable.fnDraw();
          dc.redrawAll();
          d3.selectAll(".pie-slice").call(d3Tip);
          d3.selectAll(".pie-slice").on("mouseover", d3Tip.show)
          .on("mouseout", d3Tip.hide);
          });
  };

  for (var i = 0; i < dc.chartRegistry.list().length; i++) {
      var chartI = dc.chartRegistry.list()[i];
      chartI.on("filtered", RefreshTable);
  };

现在,每当用户与一组 C3.js 图表交互时,我都需要插入一个新的数据列。此数据已包含在我正在使用的数据集中,但根据用户点击的内容,特定字段的数据或 "keyword" 应该从数据集中 return 然后添加到 table.

这些是图表本身的 onclick() 方法中的声明,将在用户点击图表后 运行。

//First Declare keyword to represent the field that is being added
var keyword = ThisChart.keyword.toString()

//Append Column Name to Table's HTML 
$('#dc-data-table thead tr').append('<th id="keyword_col">'+ keyword +'</th>');

//Access aoColumns from fnSettings and push Column Data object in.
datatable.fnSettings().aoColumns.push({
   "mData": keyword,
   "sDefaultContent": ""
});

//RefreshTable() to update the DataTable
RefreshTable()

但是这会引发错误

未捕获类型错误:oCol.fnGetData 不是函数

你知道我做错了什么吗?或者使用我当前的设置将列动态注入数据 table 的更好方法?

任何建议都会有所帮助,不胜感激。

谢谢。

我解决了这个问题。

本质上,简单地将新字段从 datatable.fnSettings() 推入 aoColumns 不会更新包含在该特定对象中的大量元素。您需要再次 运行 datatable = $("#dc-data-table").dataTable() 来设置那些需要的 methods/attributes.

我将基本的数据表设置存储在一个对象中并将其声明为全局变量。然后我可以通过任何方法更改该变量并一遍又一遍地重写数据表。

因此这是我的技巧:

//Define Initial Table

var oTable = {
      "bSort": true,
      "bInfo": false,
      "bAutoWidth": false,
      "bInfo": true,
      "bDeferRender": true,
      "aaData": tabledim.top(Infinity),
      "bDestroy": true,
      "aoColumns": [
            { "mData": "name",
              "mRender": function(client) {
                 var res = '<a href="/URL/To/Person/' + client + '/" target="_blank">' + client + '</a>';
            return res;}},
            { "mData": "date_call_rcvd",
              "mRender": function(d) {return dtFormat2(parseDate(d));}},
            { "mData": "age",
              "sDefaultContent": ""},
            { "mData": "gender",
              "sDefaultContent": ""}
          ],
          "aaSorting": [[0, "asc"]],
          "iDisplayLength": 25
  };

var datatable = $("#dc-data-table").dataTable(oTable);

//Inject Keyword as new Column then Update

chart.onClick(function(d){
  clearAll();
  $('#dc-data-table thead tr').append('<th id="keyword_col">'+ keyword +'</th>');
  oTable.aoColumns.push({
     "mData": keyword,
     "sDefaultContent": ""
  });
  datatable = $("#dc-data-table").dataTable(oTable);
  RefreshTable();
})

// Clear Function to Remove Column

function clearAll(){
 if(oTable.aoColumns.length > 4){
     oTable.aoColumns.pop();
     datatable = $("#dc-data-table").dataTable(oTable);
 }
 RefreshTable();
 dc.filterAll();
 dc.renderAll();
}; 

我担心这可能不是最有效的解决方案,也许不是最快的方法,因为我现在声明两个全局变量并在用户点击时不断呈现数据表。请随意提出更好的方法,我们将不胜感激。