使用 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 的更改正在应用于(在虚拟 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/