如何在没有 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;
就是这样,效果很好。
我用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;
就是这样,效果很好。