新冠病毒的疫情使得在线办公成为了一个常态,这使得在线文档成为了时下的热点。其中在线协同表格是在线文档的重要一个组成部分,纯前端表格在在线协同表格上有着得天独厚的劣势:自身曾经实现了单人操作在线文档的基本功能,并且身为控件,用户只需引入就能够在我的项目工程中为个性的业务赋予在线表格的能力。这样开发者在应用本文介绍内容后,只须要在其根底上自行实现对应的协同性能,就能够将自身的单人操作变为协同操作。
最近也有很多学员想要通过咱们的命令来作为协同的次要实现伎俩,然而参考了一些教程之后,发现有些操作无奈进行同步,例如粘贴以及粘贴之后的撤销操作。这篇教程次要就是分享这个实现思路。
正式开始内容介绍之前,咱们先为大家介绍命令机制。
通过监听命令来实现简略的协同操作
何为命令机制:
命令就是将一步或多步的操作封装成一个能够执行的命令,执行这样的命令并传入对应的参数,就能够执行相干的一连串操作。并且操作的对象或范畴均能够通过参数的调整来指定。命令的相干办法调用参考上面的 API:
https://demo.grapecity.com.cn…
命令到底有什么理论的意义呢?
首先,纯前端表格默认会将所有的用户 UI 操作封装成命令去执行(内置命令),而咱们通常的代码设置并没有通过命令来执行。这样就能够用来辨别一个操作到底是用户 UI 操作(最终用户应用时的操作),还是代码逻辑进行的操作(程序员通过写代码实现,即程序外部的运行逻辑)。
其次,命令自身能够设置是否能够被撤销(undo),联合上一条就能够做到将用户的操作进行撤销,然而程序执行的代码操作不会被进行撤销的操作。在理论利用中有很重要的价值,举个例子:
SpreadJS 默认初始化的电子表格是一个空表格,咱们常常遇到关上页面后须要加载一个有数据的表格这样的场景,咱们往往会将表格初始化的操作通过代码在 js 中运行来实现这样的成果。当咱们加载好表格之后,在页面上按 ctrl+ z 进行撤销,会发现设置的表格不会被撤销。这就是因为程序执行的代码操作不是命令所以不会被撤销的后果。而用户在表格上批改的任何操作均能够被撤销,撤销的同时不会影响之前代码设置这部分的内容。
命令对于在线协同的利用:
命令的机制咱们能够分清操作到底是代码执行的还是用户 UI 去操作的,而在线协同的场景中须要同步的内容就是用户 UI 的相干操作。所以咱们只须要有一个监听的机制,能监听到所有的命令,而后依照程序进行同步,就能够做到一个简略的在线协同操作了。
而在命令 command 中是能够增加一个 anyscLicenser 用于收集用户操作触发的命令的:
spread.commandManager().addListener("anyscLicenser",function(){for(var i=0;i<arguments.length;i++){var cmd = arguments[i].command;
console.log(cmd);
}
});
通过这样的监听,咱们就能够实现一个简略的多人同步的成果。而命令自身是能够自定义的,咱们能够将提供给用户操作的接口(input,按钮,下拉等)的实现逻辑封装成一个个自定义命令,就像附件的 demo 这样。这样就能够做到通过命令来收集用户在表格上的操作,来实现一个简略的协同。
这里要留神的是,尽管有命令这样的机制,但其初衷并不是为了协同而设置的,所以有些状况下源生的命令并不能齐全的合乎协同的实现,须要依据理论状况本人进行革新来满足。提供的 demo 以及命令实现的形式可当做思路可供参考。
demo 下载地址:https://gcdn.grapecity.com.cn…
可粘贴柯撤销的多人协同
那最原始通过命令的形式为什么无奈将粘贴命令同步呢?因为对于 clipboardPaste 命令,禁止将工作表的一个区域从工作簿复制到另一个工作簿,但容许内部粘贴。因而,有一种解决办法能够重置命令选项的 fromSheet 和 fromRanges。附上外围代码
var undoManager1 = spread1.undoManager();
var oldExecute = commandManager.execute;
commandManager.execute = function () {console.log(arguments,'execute');
excute(...arguments)
return oldExecute.apply(this, arguments);
};
var undoManager = spread.undoManager();
var oldUndo = undoManager.undo;
undoManager.undo = function () {undo(...arguments)
return oldUndo.apply(this, arguments);
};
var oldRedo = undoManager.redo;
undoManager.redo = function () {redo(...arguments)
return oldRedo.apply(this, arguments);
};
// websocket 承受端执行
const redo =function (params){console.log(params,'params');
undoManager1.redo.apply(undoManager1, [params]);
}
const undo =function (params){console.log(params,'params');
undoManager1.undo.apply(undoManager1, [params]);
}
const excute = (params)=>{console.log(params,'params');
var params1 = params;
if(params1.cmd === 'clipboardPaste'){params1 = Object.assign({}, params1);
params1.fromSheet=spread1.getSheetFromName(params1.sheetName);
}
commandManager1.execute.apply(commandManager1, [params1]);
}
demo 下载地址:https://gcdn.grapecity.com.cn…
大家如果感兴趣自行依照 demo 下载地址体验即可。
拓展浏览
React + Springboot + Quartz,从 0 实现 Excel 报表自动化
电子表格也能做购物车?简略三步就能实现
应用纯前端类 Excel 表格控件 SpreadJS 构建企业现金流量表