[]
        
(Showing Draft Content)

アンドゥ

共同編集のシナリオでは、アンドゥ(元に戻す)/ リドゥ(やり直し)のオペレーションもサポートされます。

本セクションでは、これらの操作について詳しく説明します。

アンドゥスタックの保存

共同編集でのすべての変更は、他のクライアントおよびサーバーと同期する必要があるため、アンドゥの結果も同期する必要があります。これは、アンドゥの結果が Ops の形式で保存されることを意味します。したがって、アンドゥスタックには Ops が保存され、Ops で表現できない挙動(例:選択の状態)は元に戻せません。

アンドゥの内容

共同編集では、各ユーザーが変更を行い、他のユーザーからの変更を受信できます。アンドゥアクションは、他者のオペレーションではなく、ユーザー自身のオペレーションのみを元に戻す必要があります。

アンドゥの競合

アンドゥはユーザー自身のオペレーションにのみ影響するため、ユーザーのオペレーションが元に戻される前に他のクライアントからのオペレーションを受信した場合、ユーザーの アンドゥは他のクライアントのオペレーションと併せて変換する必要があります。

例:

  • Alice はセル (1,1) の値を "old" から "new" に変更します。つまり sheet.setValue(1,1,'new'); です。

  • Bob は位置 0 に行を挿入します。つまり sheet.addRows(0,1); です。

  • Alice はアンドゥを実行し、(1,1) ではなくセル (2,1) の値を変更します。つまり sheet.setValue(2,1, 'old'); です。

  • Alice はリドゥを実行し、(1,1) ではなく (2,1) も変更します。つまり sheet.setValue(2,1,'new'); です。

この例から、アンドゥとリドゥは初回実行時と異なる場合があることが分かります。アンドゥとリドゥは、他のクライアントのオペレーションによって変換された結果を実行します。

使用方法

共同編集におけるアンドゥは、コラボレーション固有の機能です。非コラボレーションのシナリオでは、従来どおり通常の アンドゥ が使用されます。

アンドゥの使用方法は変更されていません。引き続きコマンド経由で実行する必要がありますが、いくつかの違いがあります。ここでは次のコマンドを例にします。

以下は色を変更する通常のコマンドです:

image

コマンド内のコードは 2 つの部分に分かれています。

非コラボレーションのシナリオでは:

  • 実行: コードセグメント 1 を実行します

  • アンドゥ: コードセグメント 2 を実行します

  • リドゥ: コードセグメント 1 を実行します

共同編集のシナリオでは、アンドゥ/リドゥは Ops を実行するため、コマンドのコードは実行されません。したがって:

  • 実行: コードセグメント 1 を実行します

  • アンドゥ: 別のコードを実行します

  • リドゥ: 別のコードを実行します

コマンドの実行ロジックは変わりますが、共同編集でのアンドゥは、既存のコマンド実装と互換性があります。ユーザーは、修正を行わずに上記のように記述されたコマンドでアンドゥをサポートできます。

API

アンドゥとリドゥはコマンド内のロジックを実行しないため、従来はアンドゥとリドゥの際にコマンド内でトリガーされていたイベントはトリガーされません。ユーザーが自身のシナリオ(例:自身の UI の更新)を処理するための適切なタイミングを提供するために、共同編集でのアンドゥのタイミングを提供する 4 つの新しいイベントが追加されました。

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);
});