如何在没有 ajax 调用的情况下使用 DataTables 从浏览器上的套接字更新实时数据?

How to Update live data from socket on browser with DataTables without ajax calls?

我用webtcp在socket和websocket之间搭建了一座桥梁。然后我能够在浏览器上显示数据,但是除非我刷新整个页面,否则它不会实时更新。它需要不断更新以显示所有数据。这就是我获取数据、解析数据并更新数据的方式。

socket.on('data', function (data) {

    var arr = data.split("|").slice(1);
    var dataSet = {};
    arr.map((o, i) => {
        if ((i + 1) % 2 != 0) dataSet[o] = arr[i + 1];
    });
    console.log(dataSet);

    $(document).ready(function () {
        $("#example").DataTable({
            retrieve: true,
            deferRender: true,
            searching: false,
            paging: false,
            "data": [dataSet],
            "columns": [
                {"data": "power"},
                {"data": "mode"},
                {"data": "execution"},
                {"data": "Xact"},
                {"data": "Yact"},
                {"data": "Zact"},
                {"data": "Xcom"},
                {"data": "Ycom"},
                {"data": "Zcom"},
                {"data": "path_feedrate"},
                {"data": "line"},
                {"data": "Block"},
                {"data": "program"}
            ],
        });
    });
});

这是我的 html:

<table id="example" class="display" width="100%">
    <thead>
    <tr>
        <th>Power</th>
        <th>Mode</th>
        <th>Execution</th>
        <th>Xact</th>
        <th>Yact</th>
        <th>Zact</th>
        <th>Xcom</th>
        <th>Ycom</th>
        <th>Zcom</th>
        <th>path_feedrate</th>
        <th>line</th>
        <th>Block</th>
        <th>program</th>
    </tr>
    </thead>
</table>

这是我的数据在控制台和浏览器上的显示方式,它在控制台上更新,因为水刀机器正在工作,但在浏览器上没有:

这是来自套接字的原始数据的样子:

2018-08-14T22:17:00.0631|Xcom|0.00|Ycom|0.00|path_feedrate|0.00
2018-08-14T22:17:00.0683|line|389286|Block|389286
2018-08-14T22:17:00.0709|Xact|402.79|Yact|33.84|Xcom|38.71|Ycom|24.19|path_feedrate|45.65
2018-08-14T22:17:00.0735|Xcom|0.00|Ycom|0.00|path_feedrate|0.00
2018-08-14T22:17:00.0787|line|389288|Block|389288
2018-08-14T22:17:00.0840|Xact|402.78|Xcom|19.36|path_feedrate|19.36
2018-08-14T22:17:00.0866|Xcom|0.00|path_feedrate|0.00|line|389290|Block|389290
2018-08-14T22:17:00.0944|Xact|402.75|Yact|33.83|Xcom|58.07|Ycom|24.19|path_feedrate|62.91
2018-08-14T22:17:00.0970|Xcom|0.00|Ycom|0.00|path_feedrate|0.00|line|389292|Block|389292

等等....

您首先等待文档加载是正确的,但此后用于填充 table 的代码不会再次 运行ning,直到再次加载文档(刷新)。

将填充 table 的代码放入函数中,并让它检查 document.readyState 属性,一旦 DOM 为 运行已加载:

function fillDataTable(dataSet){
  if(document.readyState === "complete") {
    $("#example").DataTable({
        retrieve: true,
        deferRender: true,
        searching: false,
        paging: false,
        "data": [dataSet],
        "columns": [
            {"data": "power"},
            {"data": "mode"},
            {"data": "execution"},
            {"data": "Xact"},
            {"data": "Yact"},
            {"data": "Zact"},
            {"data": "Xcom"},
            {"data": "Ycom"},
            {"data": "Zcom"},
            {"data": "path_feedrate"},
            {"data": "line"},
            {"data": "Block"},
            {"data": "program"}
        ],
    });
  }
}

然后在socket.on方法中调用:

socket.on('data', function(data) {

  const arr = data.split("|").slice(1);
  let dataSet = {};
  arr.map((o, i) => {
    if ((i + 1) % 2 != 0) dataSet[o] = arr[i + 1];
  });
  console.log(dataSet)

  fillDataTable(dataSet)

});

答案比我想象的要简单,而且最好不要使用任何外部库和表。

 <div class="cell">
        <div class="row">
            <div class="cell">
                <div class="info">
                    <div>POWER:</div>
                    <div>MODE:</div>
                    <div>EXECUTION:</div>
                    <div>BLOCK:</div>
                    <div>LINE:</div>
                    <div>FEEDRATE:</div>
                    <div>PROGRAM:</div>
                </div>
            </div>
            <div class="cell">
                <div class="live-data">
                    <div id="power"></div>
                    <div id="mode"></div>
                    <div id="execution"></div>
                    <div id="block"></div>
                    <div id="line"></div>
                    <div id="feedrate"></div>
                    <div id="program"></div>
                </div>
            </div>
        </div>
    </div>

这是我的 js:

    if (dataSet.power) document.getElementById("power").innerHTML = dataSet.power;
    if (dataSet.mode) document.getElementById("mode").innerHTML = dataSet.mode;
    if (dataSet.execution) document.getElementById("execution").innerHTML = dataSet.execution;
    if (dataSet.block) document.getElementById("block").innerHTML = dataSet.block;
    if (dataSet.line) document.getElementById("line").innerHTML = dataSet.line;
    if (dataSet.path_feedrate) document.getElementById("feedrate").innerHTML = dataSet.path_feedrate;
    if (dataSet.program) document.getElementById("program").innerHTML = dataSet.program;
    if (dataSet.Xact) document.getElementById("xact").innerHTML = dataSet.Xact;
    if (dataSet.Yact) document.getElementById("yact").innerHTML = dataSet.Yact;
    if (dataSet.Zact) document.getElementById("zact").innerHTML = dataSet.Zact;
    if (dataSet.Xcom) document.getElementById("xcom").innerHTML = dataSet.Xcom;
    if (dataSet.Ycom) document.getElementById("ycom").innerHTML = dataSet.Ycom;
    if (dataSet.Zcom) document.getElementById("zcom").innerHTML = dataSet.Zcom;

就是这样,效果很好。