[]
        
首页
开发者学堂
文档
论坛
市场
生态机会
活动
在线咨询 立即试用
(Showing Draft Content)

协同撤销机制

在协同场景中,撤销(Undo)和重做(Redo)操作同样得到支持。本文档将详细介绍相关机制。

撤销栈存储机制

由于协同中的所有修改都需要与其他客户端和服务器同步,撤销操作的结果也必须同步。这意味着撤销操作的结果以操作(Ops)的形式存储。因此,撤销栈中存储的是操作,而无法用操作表示的行为(如选择状态)则无法被撤销。

撤销内容范围

在协同环境中,每个用户可以进行修改并接收他人的修改。撤销操作仅应撤销用户自己的操作,而不包括他人的操作。

撤销冲突处理

由于撤销仅影响用户自己的操作,如果在用户的操作被撤销前接收到了其他客户端的操作,则用户的撤销可能需要与这些操作进行转换。

例如:

  • Alice 将单元格 (1,1) 的值从 "old" 改为 "new",即 sheet.setValue(1,1,'new');

  • Bob 在位置 0 插入一行,即 sheet.addRows(0,1);

  • Alice 执行撤销操作,此时修改的是单元格 (2,1) 而非 (1,1),即 sheet.setValue(2,1, 'old');

  • Alice 执行重做操作,同样修改的是 (2,1) 而非 (1,1),即 sheet.setValue(2,1,'new');

从这个例子可以看出,撤销和重做操作的结果可能与初始执行不同。撤销和重做操作执行的是与其他客户端操作转换后的结果。

使用方法

协同撤销是协同场景特有的功能。在非协同场景中,撤销仍使用非协同的撤销方法。

撤销的使用方式没有变化,仍需通过命令执行,但存在一些差异。以下面的颜色修改命令为例:

undo

命令中的代码分为两部分:

  • 非协同场景

    • do:执行代码段 1

    • undo:执行代码段 2

    • redo:执行代码段 1

  • 协同场景

    由于撤销/重做操作执行的是操作(Ops),而非命令代码,因此:

    • do:执行代码段 1

    • undo:执行其他代码

    • redo:执行其他代码

虽然命令的执行逻辑发生了变化,但协同撤销与命令兼容。用户可以直接使用上述方式编写的命令支持协同撤销,无需修改。

API

由于撤销和重做操作不执行命令内部的逻辑,因此之前在命令中触发的事件在协同撤销时将不再触发。为了给用户提供处理其场景的适当时机(例如更新自己的 UI),新增了四个事件来提供协同撤销的时机:

interface IChangeSet {
  ops: IOpComponent[];
}
workbook.bind(GC.Spread.Sheets.Events.CollaborationStartUndo, (sender, args: { changeSet: IChangeSet  }) => {
    const changeSet = args.changeSet;
    console.log('undo changeSet is:', changeSet);
});
workbook.bind(GC.Spread.Sheets.Events.CollaborationEndUndo, (sender, args: { changeSet: IChangeSet  }) => {
    const changeSet = args.changeSet;
    console.log('undo changeSet is:', changeSet);
});
workbook.bind(GC.Spread.Sheets.Events.CollaborationStartRedo, (sender, args: { changeSet: IChangeSet  }) => {
    const changeSet = args.changeSet;
    console.log('redo changeSet is:', changeSet);
});
workbook.bind(GC.Spread.Sheets.Events.CollaborationEndRedo, (sender, args: { changeSet: IChangeSet  }) => {
    const changeSet = args.changeSet;
    console.log('redo changeSet is:', changeSet);
});

底层 API

协同撤销栈存储的是操作(Ops),Op 的 srcseq 字段用于区分不同客户端提交的操作,是"仅撤销自己操作"这一行为的基础。关于 Op 的字段定义与版本管理机制,参见 底层协同框架 中的 操作(Op)