我有一个设置,可以在 JavaScript 端点中使用 Python/Flask 获取连续数据。我的目标是——
1/ 用完美的数据创建表格。
2/ 按添加按钮(在父表的每一行中)创建子表。这也正常工作。
所有表(父和子)都有唯一的ID,并且都位于唯一的 div 中。
我的 ParentTable 一直在更新,因为我每秒都在从 Python 获取数据。 问题是我的ChildTable没有更新。 ChildTable 创建后我还可以通过什么方式更新?
为此,我正在考虑一种方法(在代码 updateChild
函数中)--
1/ 我将遍历ChildTable的第一列数据,并将它们存储在一个数组中。例如:child_table_col = [row_a_3, row_a_1]
2/ChildTable 第一列数据的层次结构与ParentTable 不同。例如:ChildTable 的第一列可以是 [row_a_3, row_a_1]
而 ParentTable 的 的第一列将始终是 [row_a_1, row_a_2, row_a_3].
在这里,我想如果在这里我可以找到任何可以告诉 ParentTable
的方法
-----a) 检查number 1
中创建的数组中的内容,并一一取下一个td
值。所有表都有 3 column
,所以每行都有 3 td
。如果我能说
/*
child_col_table array lengh is suppose 3 (with header)
each row td value has 3 times(first one is nothing but the same content of the Chlid and Parent key)
*/
for(let i =0; i<child_col_table.length;i++){
for(let j =1;j<3;j++){
ChildTable[child_table_col[i]][td[j]] = ParentTable[child_table_col[i]][td[j]]
}
}
/* I know that my thinking is not possible as it is not a JSON format or something like that.*/
那么也许我可以更新ChildTable。我在这里给出了一个工作示例。我尝试过一种方法,其中每 2 秒表数据也会改变,但我在这里没有做到。
因此,再次简而言之,当我的 ParentTable 一直在更新时,我如何更新我的 ChildTable?
tabledata =
{
"device_0a":
{
"row_1":{"a":"row_a_1", "b":3,"c":5},
"row_2":{"a":"row_a_2", "b":5,"c":6},
"row_3":{"a":"row_a_3", "b":7,"c":9}
},
"device_0b":
{
"row_1":{"a":"row_b_1", "b":-3,"c":8},
"row_2":{"a":"row_b_2", "b":2,"c":6},
"row_3":{"a":"row_b_3", "b":3,"c":4}
}
}
function createTable(caption, data, family_table_div_val, addbutton = true) {
let table = $("<table class='test_table'>");
table
.html("<caption>" + caption + "</caption>")
.attr("id", caption);
let headers = getColumns(data[Object.keys(data)[0]]);
let tr = $("<tr>");
for (let i in headers) {
tr.append("<th>" + headers[i] + "</th>");
}
table.append(tr);
for (let row in data) {
let tr = $("<tr>");
for (let col in data[row]) {
let format_data = check_input_val_type(data[row][col], 1);
let td = $("<td>").text(format_data);
tr.append(td);
}
if (addbutton) {
let td_btn = $("<td>")
.addClass("table_button")
.text("Add")
.click(function() {
clicked_parent_tbl_id = $(this).closest('table').attr('id');
child_div_id = family_table_div_val + "_Child";
tbl_div_child = $("<div>")
.attr("id", child_div_id)
.addClass("child_table_class");
if ($('#' + tbl_div_child.attr("id")).contents().length == 0) {
new_tbl_1 = createTable(caption + "_Child", { row: data[row] }, 0, false);
tbl_div_child.append(new_tbl_1);
$('#' + family_table_div_val).prepend(tbl_div_child);
}
else {
var values = [];
var count = 0;
$(this).closest("tr").find("td").each(function() {
values[count] = $(this).text();
count++;
});
my_tr = $('<tr/>');
for (var j = 0; j < values.length - 1; j++) {
my_tr.append("<td>" + values[j] + "</td>");
}
var arr = [];
$('#' + clicked_parent_tbl_id + "_Child" + " tr").each(function() {
arr.push($(this).find("td:first").text());
});
validity = arr.includes(values[0]);
if (validity === false) {
$('#' + clicked_parent_tbl_id + "_Child" + " > tbody").append(my_tr);
}
}
});
tr.append(td_btn);
}
table.append(tr);
}
return table;
}
function getColumns(data) {
let headers = [];
for (let col in data) {
headers.push(col);
}
return headers;
}
/**
* Check value is float or int or string and return value. IF ffloat then it will round to a give fixed point. You can omit it if not required
*/
function check_input_val_type(y, fixed_range) {
if (parseFloat(y) && (Number(y) === y && y % 1 !== 0)) {
// console.log("y is a float and val is: ", y, " and conv: ", y.toFixed(fixed_range));
y = y.toFixed(fixed_range);
return y;
} else if (!parseFloat(y)) {
// console.log("y is a string and val is: ", y);
return y;
} else {
// console.log("y is a int and val is: ", y);
return y;
}
}
/** following function helps to track old child info. Here old means
* while function table_with_vanilla_js() is called with a given interval
* then new data came from the FLask endpoint to JS endpoint and whole page refresh
* to update parent table. For the firts time(while no chold table is created) then
* histoy of chold table is undoubtedly ZERO/ NULL. But if any child table is cretaed
* by clicking the ADD button of the parent table then it is necessary to track child
* table history. The following function does it properly
* */
jQuery.expr[':'].regex = function(elem, index, match) {
var matchParams = match[3].split(','),
validLabels = /^(data|css):/,
attr = {
method: matchParams[0].match(validLabels) ?
matchParams[0].split(':')[0] : 'attr',
property: matchParams.shift().replace(validLabels, '')
},
regexFlags = 'ig',
regex = new RegExp(matchParams.join('').replace(/^\s+|\s+$/g, ''), regexFlags);
return regex.test(jQuery(elem)[attr.method](attr.property));
}
function updateChild(child, parent) {
let child_table_id = child.childNodes[0].id;
let parent_table_id = child_table_id.slice(0, -6);
/** get table row and col length. it is now also count header as a tr */
var get_child_table = document.getElementById(child_table_id); /** get child table */
let child_table_row = get_child_table.rows.length /** row length */
let child_table_col = get_child_table.rows[0].cells.length; /** col length */
var get_parent_table = document.getElementById(parent_table_id); /** get parent table */
/** traversing through the child table */
for (let i = 0; i < child_table_row; i++) {
for (let j = 0; j < child_table_col; j++) {
// console.log("data[", i, "][", j, "]: ", get_child_table.rows[i].cells[j].textContent)
}
}
/** get the data of first col from child table */
let first_col_data_child_table = [];
for (let i = 1; i < child_table_row; i++) { /** initiate at 1 bcz then column header which is also a row we can omit */
for (let j = 0; j < 1; j++) {
first_col_data_child_table.push(get_child_table.rows[i].cells[j].textContent);
}
}
console.log("first_col_data_child_table: ", first_col_data_child_table);
}
function table_with_vanilla_js(data) {
let tbl_div = $("#table_div");
let children = $("div:regex(id, .*_child)");
tbl_div.html("");
for (let t in data) {
family_table_div = $("<div>")
.attr("id", "Family_" + t)
.addClass("family_table_class");
parent_table_div = $("<div>")
.attr("id", family_table_div.attr("id") + "_Parent")
.addClass("parent_table_class");
new_tbl = createTable("Table_" + t, data[t], family_table_div.attr("id"));
tbl_div.append(family_table_div);
family_table_div.append(parent_table_div);
parent_table_div.append(new_tbl);
}
for (let i = 0; i < children.length; i++) {
let child = children[i];
let parent = child.id.slice(0, -6);
$("#" + parent).prepend(child);
updateChild(child, parent);
}
}
table_with_vanilla_js(tabledata);
.test_table {
float: left;
margin-right: 20px;
}
.test_table td,
.test_table th {
border: 1px solid white;
padding: 8px;
}
.test_table tr:nth-child(even) {
background-color: #f2f2f2;
}
.test_table tr:hover {
background-color: #ddd;
}
.test_table th {
padding-top: 12px;
padding-bottom: 12px;
text-align: center;
background-color: #4CAF50;
color: white;
}
.table_button {
background-color: #515151;
color: white;
}
.table_button:hover {
background-color: #707070;
}
.table_button:active {
background-color: #aaa;
}
#table_div_child {
background-color: red;
}
#table_div {
float: left;
z-index: 0;
position: absolute;
margin-top: 50px;
background-color: #dfd117f5;
}
.family_table_class {
float: left;
background-color: #FFC0CB;
}
.parent_table_class {
background-color: #FFA500;
}
.child_table_class {
float: left;
background-color: #87ceeb;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
<meta charset="UTF-8">
<title>Build Table with Vanilla JS</title>
</head>
<body id="body" style="margin-top: 0">
<div id="table_div"></div>
</body>
</html>