如何在 RangeChanged 中实现一些 canUndo 的操作
比如 RangeChanged 并且 info.action === Spread.Sheets.RangeChangedAction.clear 时,我将对应的 cell 的 backColor 都设置为 red。此时用户 ctrl+z 了,那内容和 backColor 都应该同时变回去,如何实现?
将需要同时撤销的操作 写到同一个命令里,用自定义命令来实现,这样撤销时会撤销整个命令:
自定义命令的学习指南:https://demo.grapecity.com.cn/spreadjs/SpreadJSTutorial/features/worksheet/actions/custom-action/purejs 没法写到一起,因为内容是 clear 删除的,不是我删除的,我只能收到 RangeChanged 事件,得知内容被清除,然后我再操作 backColor 在自定义command中,通常会有一个isUndo的参数来标记当前执行栈是execute还是undo的操作,那么在isUndo条件满足时,可以通过flag的方式来多撤销一步,如下代码所示:
command = {
canUndo: true,
execute: function (context, options, isUndo) {
Commands = GC.Spread.Sheets.Commands;
if (isUndo) {
Commands.undoTransaction(context, options);
if(flag){
context.undoManager().undo()
flag = false;
}
return true;
} else {
Commands.startTransaction(context, options);
var sheet = context.getSheetFromName(options.sheetName);
sheet.frozenRowCount(options.rowCount);
Commands.endTransaction(context, options);
return true;
}
}
}; KevinChen 发表于 2020-6-16 15:57
在自定义command中,通常会有一个isUndo的参数来标记当前执行栈是execute还是undo的操作,那么在isUndo条件 ...
我测试了下,在 RangeChanged 的处理函数里,commandManager.execute 执行一个命令,然后 ctrl + z,在 execute 的函数中输出 console.log('execute', options, isUndo),拿到了两次执行的 isUndo 都是 false。
是 bug 吗 你好,这个问题原因找到了,是由于undo clear操作也会触发RangeChanged ,在RangeChanged 中无法判断是否为undo引发的,所以导致了两次执行isUndo都是false。
是否可以考虑用条件格式实现?当指定区域被clear为空时,某些区域显示为red即可。 本帖最后由 nutstore 于 2020-6-17 09:11 编辑
KevinChen 发表于 2020-6-16 18:27
你好,这个问题原因找到了,是由于undo clear操作也会触发RangeChanged ,在RangeChanged 中无法判断是否为 ...
呃,这里标记为 red 是一个例子,我实际上想做的事情是 setCellType 与 setHyperLink,有没有什么其他方法能够实现随着 RangeChanged 一起撤销?
这种需求应该是比较常见的,在 RangeChanged 里做一些事情,并希望它能随着撤销一起回归原样。
可以尝试重写undo redo方法,来加如自己的undo和redo逻辑。参考附件示例。
本帖最后由 nutstore 于 2020-6-17 11:41 编辑
KevinChen 发表于 2020-6-17 10:01
可以尝试重写undo redo方法,来加如自己的undo和redo逻辑。参考附件示例。
这种写法感觉会有很多坑,因为 flag 的发布者有很多但无法确定,消费者只有 RangeChanged 中的处理函数,它无法得知这个 flag 是否是它应该消费的。
我目前用了另一种方式,在 RangeChanged 中 commandManager.execute 上,包一层 setTimeout,目前看起来可以拿到 isUndo: true 了,这样是否会有什么隐患? nutstore 发表于 2020-6-17 11:38
这种写法感觉会有很多坑,因为 flag 的发布者有很多但无法确定,消费者只有 RangeChanged 中的处理函数, ...
正常逻辑是这样,当RangeChanged触发时,实际上clear命令还没有执行完,那么RangeChanged回调执行完成时,命令栈里是先有我们调用的命令(例如设置red),才有clear,撤销时同理。
所以用setTimeout才能避免这个问题。
目前没什么太好的办法,我提个需求,让研发在RangeChanged中加个参数,标识一下是否Undo操作,像这个事件一样:
https://demo.grapecity.com.cn/spreadjs/help/latest/content/SpreadJS~GC.Spread.Sheets.Events~RowChanged_EV.html
页:
[1]
2