Richard.Ma 发表于 2024-7-4 18:14:32

如何修改Spread内置的Command命令

本帖最后由 Richard.Ma 于 2024-7-5 09:10 编辑

Spread提供了Command机制来实现对一个操作的执行,撤销和重做。用户在UI上做的大部分操作实际上都是通过执行内置的Command来完成的。

在示例中,也提供了创建一个新的自定义Command的方法
https://demo.grapecity.com.cn/sp ... ustom-action/purejs

但是对于一些用户来说,希望能修改或者说重写控件已有的一些Command,在执行原因逻辑的基础上,在之前或之后加入自定义的一些逻辑。在并且仍然保持能被撤销和重做

这篇教程,以控件已有的命令GC.Spread.Sheets.Commands.editCell 为例介绍如何重写这个命令,

editCell 命令,会在用户对单元格编辑结束后触发,我们尝试重写这个命令,除去原有逻辑外,给被编辑的单元格的右侧单元格也设置一个自定义的值作为标识,

关键代码
//取到原有的editCell的excute方法
      var oldExcute= GC.Spread.Sheets.Commands.editCell.execute;

      //重写editCell的excute方法,仅改变返回结果为false,以阻止这个方法本身会被添加到undoList中
      var newExcute=function (context, options, isUndo) {
            oldExcute (context, options, isUndo) ;
            return false;
      }

      //新的editCell命令定义,
      let NewEditCell = {
            canUndo: true,
            name: "editCell",
            execute: function (context, options, isUndo) {
                  console.log(options);
                  let Commands = GC.Spread.Sheets.Commands;
                  if (isUndo) {
                        Commands.undoTransaction(context, options);
                        return true;
                  } else {
                        Commands.startTransaction(context, options);
                        let sheet = context.getSheetFromName(options.sheetName);

                        sheet.suspendPaint();

                        //在前面先调用自定义的逻辑代码
                        sheet.getCell(options.row, options.col+1).value("["+options.row+","+options.col+"]已修改");
                        console.log(options.cmd);

                        //调用已经重写的editCell的excute方法,执行原有的逻辑
                        newExcute(context, options, isUndo);

                        //在后面执行自定义的逻辑代码
                        sheet.resumePaint();
                        Commands.endTransaction(context, options);
                        return true;
                  }
            },
      };
      //将新的editCell命令注册到spread的commandManager中,替代原有的editCell命令
      spread.commandManager().register("editCell", NewEditCell);

上述代码设置后,在编辑单元格时的效果动态图如下:

可以看到在原有的单元格值被设置时,自定义的代码也在事务中被执行了,且同时可以被撤销和重做。






Dtttax 发表于 2024-7-8 17:14:28

如果涉及到多个sheet的撤回呢,也就是NewEditCell 方法里面动态的可能有多个sheet设置值。.我看了下这个是在外面重新注册editCell。所以sheetName参数不好传。

Richard.Ma 发表于 2024-7-9 10:26:44

NewEditCell是去重写了editCell命令,spreadjs原本的代码在调用这个命令得到时候,传入的就只有当前的sheetName,这是源码里面写死的。你没法更改。

原有的editCell命令本身就是用来只设置单元格值的。你如果要做一些不相关的操作,就不应该想着去重写这个command,而是通过其他的方式,比如自己新定义一个command,通过添加ribbon或者右键菜单按钮来触发
页: [1]
查看完整版本: 如何修改Spread内置的Command命令