使用 setData() 函数将制表符数据从一个 table 复制到多个 table 会产生 unpredictable 结果
Copying Tabulator data from one table to multiple tables using the setData() function produces unpredictable results
我正在使用 Tabulator
进行客户端输入和编辑表格数据。在我的应用程序中,我需要将数据从单个 [Crew Leader] table 复制到一个或多个 [Crew Member] table。输入 [Crew Leader] 的数据后,我正在使用 button
触发向 [Crew Member] table 的复制过程。这是使用按预期工作的 Tabulator setData()
函数完成的。
将数据复制到 [Crew Member] table 后,有必要使用与个人 [Crew Member] 相关的信息编辑每一行。屏幕上的编辑过程按预期进行。
我去导出数据的时候出现了问题。注意,我的 JSON
字符串中的数据:
- 与屏幕上显示的不一样;和
- 对所有 [Crew Member] table 都是一样的。
似乎应用于一个 [Crew Member] table 的更改正在应用于(在虚拟 DOM 中)所有 [Crew Member] table。换句话说,对于两个 "cloned" table,应用于 table 的更改应用于虚拟 DOM 中的两个 table,但不在屏幕上(并且反之亦然)。
客户端脚本,用于从 [Crew Leader] table 复制到 [Crew Member] table(s):
function CloneTable() {
var tableCrewLeader = Tabulator.prototype.findTable('#CrewLeaderTable')[0];
var dataCrewLeader = tableCrewLeader.getData();
if (tableCrewLeader.getDataCount() > 0) {
// Verify a Tabulator table is present for each selected [Crew Member] by
// looping through each <div> element with the class "crew-member-card".
$(".crew-member-card").each(function () {
if ($(this).attr('id').length > 0) {
const divId = "#" + $(this).attr('id').replace('Card', 'Table');
const tableMember = Tabulator.prototype.findTable(divId);
if (tableMember.length > 0) {
const tableCrewMember = Tabulator.prototype.findTable(divId)[0];
tableCrewMember.setData(dataCrewLeader);
}
else {
console.log("The Tabulator table " + divId+ " was not found.");
}
}
});
}
}
另外值得注意的是,直接输入[Crew Member]table的数据时不会出现这些异常(没有setData()
方法)。当数据最初未复制到 table 时,屏幕 edits/changes 不会反映在其他 table 中。
值得一提的是,以下是我用来验证每个 [Crew Member] table 行内容的循环(使用 Firefox Web Console 查看日志):
var dataCrewMember = tableCrewMember.getData();
$(dataCrewMember).each(function () {
console.log(this);
});
编辑
我通过在 Tabulator
构造函数中设置 reactiveData
属性消除了屏幕上数据和导出数据之间的差异,如下所示:
var table = new Tabulator(divid, {
height: "100%",
layout: "fitDataFill",
reactiveData: true, //enable reactive data
movableRows: true,
tabEndNewRow: true,
rowContextMenu: myActionContextMenu,
keybindings: {
"navUp": true,
"navDown": true,
},
columns: [
{ title: "Phase Code", field: "Phasecode", width: 144, editor: "select", editorParams: { values: function (cell) { return window.laborPhaseCodes; } } },
{ title: "Date Worked", field: "DateComp", hozAlign: "center", sorter: "date", editor: dateEditor },
{ title: "Start Time", field: "TimeStart", hozAlign: "center", sorter: "time", editor: timeEditor },
{ title: "Finish Time", field: "TimeFinish", hozAlign: "center", sorter: "time", editor: timeEditor },
{ title: "Memo", field: "Memo", width: 144, hozAlign: "left", editor: "input" },
{ title: cloneString, headerSort: false, headerClick: CloneTable, rowHandle: true, formatter: "handle" }
],
});
但是请注意,我仍然遇到一个问题,其中一个 [Crew Member] table 中所做的更改会自动复制到其他 [Crew Member] table 中。只有在使用 setData()
方法填充 [Crew Member] table 中的数据时才会发生这种情况。
非常感谢任何帮助。
在您的 cloneTables
函数中,您设置了 dataCrewLeader = tableCrewLeader.getData()
。然后使用 dataCrewLeader
作为每个新创建的表中的值。我只能假设这些是作为参考传递的,因为它们是对象。所以,改变一个就会改变所有。 (我不知道这是否是一个错误,或者是否期望制表符在调用 setData()
时创建副本。)
解决这个问题,而不是将变量设置为值。你想多次调用 .getData()
。因此,您可以 tableCrewMember.setData(tableCrewMember.getData())
并且它会按预期工作。
您可以 comment/uncomment 下面示例中 copyData
函数内部的行来查看问题。
编辑了示例,使其无需更改任何内容即可运行。
https://jsfiddle.net/nrayburn/85ecbvys/36/
我正在使用 Tabulator
进行客户端输入和编辑表格数据。在我的应用程序中,我需要将数据从单个 [Crew Leader] table 复制到一个或多个 [Crew Member] table。输入 [Crew Leader] 的数据后,我正在使用 button
触发向 [Crew Member] table 的复制过程。这是使用按预期工作的 Tabulator setData()
函数完成的。
将数据复制到 [Crew Member] table 后,有必要使用与个人 [Crew Member] 相关的信息编辑每一行。屏幕上的编辑过程按预期进行。
我去导出数据的时候出现了问题。注意,我的 JSON
字符串中的数据:
- 与屏幕上显示的不一样;和
- 对所有 [Crew Member] table 都是一样的。
似乎应用于一个 [Crew Member] table 的更改正在应用于(在虚拟 DOM 中)所有 [Crew Member] table。换句话说,对于两个 "cloned" table,应用于 table 的更改应用于虚拟 DOM 中的两个 table,但不在屏幕上(并且反之亦然)。
客户端脚本,用于从 [Crew Leader] table 复制到 [Crew Member] table(s):
function CloneTable() {
var tableCrewLeader = Tabulator.prototype.findTable('#CrewLeaderTable')[0];
var dataCrewLeader = tableCrewLeader.getData();
if (tableCrewLeader.getDataCount() > 0) {
// Verify a Tabulator table is present for each selected [Crew Member] by
// looping through each <div> element with the class "crew-member-card".
$(".crew-member-card").each(function () {
if ($(this).attr('id').length > 0) {
const divId = "#" + $(this).attr('id').replace('Card', 'Table');
const tableMember = Tabulator.prototype.findTable(divId);
if (tableMember.length > 0) {
const tableCrewMember = Tabulator.prototype.findTable(divId)[0];
tableCrewMember.setData(dataCrewLeader);
}
else {
console.log("The Tabulator table " + divId+ " was not found.");
}
}
});
}
}
另外值得注意的是,直接输入[Crew Member]table的数据时不会出现这些异常(没有setData()
方法)。当数据最初未复制到 table 时,屏幕 edits/changes 不会反映在其他 table 中。
值得一提的是,以下是我用来验证每个 [Crew Member] table 行内容的循环(使用 Firefox Web Console 查看日志):
var dataCrewMember = tableCrewMember.getData();
$(dataCrewMember).each(function () {
console.log(this);
});
编辑
我通过在 Tabulator
构造函数中设置 reactiveData
属性消除了屏幕上数据和导出数据之间的差异,如下所示:
var table = new Tabulator(divid, {
height: "100%",
layout: "fitDataFill",
reactiveData: true, //enable reactive data
movableRows: true,
tabEndNewRow: true,
rowContextMenu: myActionContextMenu,
keybindings: {
"navUp": true,
"navDown": true,
},
columns: [
{ title: "Phase Code", field: "Phasecode", width: 144, editor: "select", editorParams: { values: function (cell) { return window.laborPhaseCodes; } } },
{ title: "Date Worked", field: "DateComp", hozAlign: "center", sorter: "date", editor: dateEditor },
{ title: "Start Time", field: "TimeStart", hozAlign: "center", sorter: "time", editor: timeEditor },
{ title: "Finish Time", field: "TimeFinish", hozAlign: "center", sorter: "time", editor: timeEditor },
{ title: "Memo", field: "Memo", width: 144, hozAlign: "left", editor: "input" },
{ title: cloneString, headerSort: false, headerClick: CloneTable, rowHandle: true, formatter: "handle" }
],
});
但是请注意,我仍然遇到一个问题,其中一个 [Crew Member] table 中所做的更改会自动复制到其他 [Crew Member] table 中。只有在使用 setData()
方法填充 [Crew Member] table 中的数据时才会发生这种情况。
非常感谢任何帮助。
在您的 cloneTables
函数中,您设置了 dataCrewLeader = tableCrewLeader.getData()
。然后使用 dataCrewLeader
作为每个新创建的表中的值。我只能假设这些是作为参考传递的,因为它们是对象。所以,改变一个就会改变所有。 (我不知道这是否是一个错误,或者是否期望制表符在调用 setData()
时创建副本。)
解决这个问题,而不是将变量设置为值。你想多次调用 .getData()
。因此,您可以 tableCrewMember.setData(tableCrewMember.getData())
并且它会按预期工作。
您可以 comment/uncomment 下面示例中 copyData
函数内部的行来查看问题。
编辑了示例,使其无需更改任何内容即可运行。 https://jsfiddle.net/nrayburn/85ecbvys/36/