2017 年 10 月 24 日星期二

在 Editor 中对更改进行排队

在向用户展示可编辑数据时,有时会希望排队执行多个更改,以便同时提交所有这些更改。Editor 的多行编辑功能可解决此问题,适用于要编辑的所有字段都具有单个值的字段,但您可能希望单独编辑各行,然后再批量提交这些行。也可以结合 Editor 实现此功能,我将在本帖中探讨如何准确实现此功能。

与往常一样,我们直接来看一个示例 - 您将在其中看到,当您编辑表中的数据时,保存更改放弃更改按钮处于启用状态。单击保存更改按钮,所做的更改将保存到服务器。单击放弃更改按钮,是的,您猜对了,所做的更改将被放弃,并恢复原始数据。

姓名 工资
姓名 工资

架构

在我们讨论用于构建此示例的代码之前,我想突出显示三个此应用程序中使用此功能时所需库的特定功能

  1. Editor 本地表编辑功能 - Editor 1.6 让 Editor 可以完全更新表中的数据,而无需提交到服务器。
  2. Editor 多行编辑 API - 以编程方式提交多行的单一请求中的数据。
  3. 自定义按钮 - 让我们定义按钮来执行我们所需的任何操作 - 在本例中是将数据提交到服务器。

将这三项与包含已编辑行的行限定符的简单数组放在一起,即可满足我们构建队列式编辑界面的所有需求。

谜题的最后一块是,我们需要为此使用两个 Editor 实例 - 第一个用于本地表编辑(未配置 ajax 选项),第二个用于提交批量编辑的 Ajax 请求(配置了 ajax 选项)。

本地表编辑

Editor 中的本地表编辑只是定义具有必需字段(fields)的 Editor 以及要编辑的目标表(table)的一个案例。将该功能与标准的 DataTable 配置相结合,我们就可以获得类似于以下内容的结果

var editorOpts = {
    table: '#myTable',
    fields: [
        {
            label: 'First name:',
            name: 'first_name'
        },
        {
            label: 'Last name:',
            name: 'last_name'
        },
        // ...
    ]
};

// Local table editing instance
var localEditor = new $.fn.dataTable.Editor(editorOpts);

// Ajax editor instance
var ajaxEditor = new $.fn.dataTable.Editor(
    $.extend(true, {
        ajax: '../php/staff'
    }, editorOpts)
);

var table = $('#myTable').DataTable({
    ajax: '../php/staff',
    columns: [
        {
            data: null,
            render: function(data, type, row) {
                // Combine the first and last names into a single table field
                return data.first_name + ' ' + data.last_name;
            }
        },
        { data: 'position' },
        // ...
    ],
    select: true,
    layout: {
        topStart: {
            buttons: [
                { extend: 'create', editor: ajaxEditor },
                { extend: 'edit',   editor: localEditor },
                { extend: 'remove', editor: ajaxEditor }
            ]
        }
    }
});

请注意,Editor 选项已放置到名为 editorOpts 的对象中 - 这允许将同一对象重复用于 localEditorajaxEditor 实例,因为它们之间的唯一区别是 ajax 选项(它使用 jQuery 的 $.extend() 方法 添加到对象中)。

对于显示在表上方的编辑按钮,localEditor 用于编辑,而 ajaxEditor 用于创建和删除行(它们会立即提交 - 如果需要,您可以在不同的队列中提交这些行)。

按钮

接下来,查看保存更改放弃更改按钮。此处我们只需要两个 自定义按钮,它们被添加到 按钮 数组,如下所示

{
    text: 'Save changes',
    init: function () {
        this.disable();
    },
    action: function () {
        // ...
    }
},
{
    text: 'Discard changes',
    init: function () {
        this.disable();
    },
    action: function () {
        // ...
    }
}

请注意,它们均定义一个 init 函数,用于默认禁用其操作。这样做是因为我们只想在用户确实编辑了一行或多行时启用它们。

因此,我们不仅需要在编辑一行时启用这些按钮,而且还必须跟踪哪些行已编辑,以便当我们需要将它们提交到服务器时,我们不需要发送表格中的每一行,从而增加开销。可以通过一个简单的数组来实现这一点,buttons().enable() 用于启用这些按钮,而 postEdit 事件用于了解它们何时应更新

// Array which will store the id's of the rows which have been locally edited (for later submission)
var changedRows = [];

editor.on('postEdit', function (e, json, data) {
    // Store the row id so it can be submitted with the Ajax editor in future
    changedRows.push( '#'+data.DT_RowId );

    // Enable the save / discard buttons
    table.buttons([3,4]).enable();
});

按钮选择器 (按钮选择器) [3,4] 表明第 3 和 4 (从 0 开始) 索引中的按钮应该被选中,这是它们在添加到 按钮 数组中的位置。

多行编辑

所有其他内容都已设置完毕,我们现在可以提交数据或放弃数据。这在用于各个按钮的 action 函数中完成(其中省略号显示在上面)。在提交操作的情况下,我们可以使用 edit() 和已编辑行的数组,然后 submit()。由于编辑器的多行编辑能力,它可以根据需要从数组中提交多行

action: function () {
    // Submit the Ajax Editor without asking for confirmation
    ajaxEditor
        .edit( changedRows, false )
        .submit();
    
    // Clear out the saved rows and disable the save / discard buttons
    changedRows.length = 0;
    table.buttons([3,4]).disable();
}

最后一部分是放弃按钮,它只是清空 changedRows 数组并再次禁用按钮。还调用 ajax.reload() 以从服务器重新加载当前保存的数据。如果你不想进行此服务器交互,还可以选择将 initEdit 中编辑的原始数据存储起来,但这是保持数据最新最有效的方法。

action: function () {
    this.ajax.reload();

    changedRows.length = 0;
    table.buttons([3,4]).disable();
}

结论

我们在此了解了如何使用编辑器的较新功能和几个自定义按钮,可以轻松创建队列编辑界面。如果你想查看用于上面运行演示的完整 Javascript,可以 在此处查看

最后几篇博文,我都专注于编辑器 - 下一篇我将回到 DataTables!与往常一样,如果你对 DataTables 的这一或任何其他方面有任何疑问或建议,请随时 在论坛中发帖。我们随时欢迎反馈。

尽情享受吧!