找回密码
 立即注册

QQ登录

只需一步,快速开始

马朝洋

注册会员

1

主题

9

帖子

26

积分

注册会员

积分
26
最新发帖
马朝洋
注册会员   /  发表于:2021-7-22 18:14  /   查看:4528  /  回复:15
用户自定义了一些操作,我将最终数据merge之后生成了新的json,通过 spread.fromJSON render出来。但是存在一个问题是用户的操作记录全部清空了,无法control+z。
我希望满足用户这个需求,需要怎么做呢?是必须要手动维护一个操作记录队列?还是有别的更好的建议?谢谢。

15 个回复

倒序浏览
马朝洋
注册会员   /  发表于:2021-7-29 10:58:08
推荐
==================最终处理方案回复=======================
之前说的写一个diff方法调用spreadJs api 做处理的思路,被放弃了,原因两点:1: 调用api生成,性能问题比较严重,很多更新没有找到批量操作的api,逐条遍历更新时间会很长。 2: 有些属性的修改没有找到设置的api,比如表格列的id等。直接用json的时候是可以修改的,但是api里不能设置。

====================================================

我最终实现方法是重写了 controlZ controlY,自己做了一个事件队列,每部变更都将最新数据记录到队列里。目前看没有什么性能问题。可以作为一个参考。


队列方法:
  1. import { spreadToJSON, jsonToSpread } from './contract.bridge'

  2. // 获取当前选中的表格

  3. export class ContractQueue {
  4.   constructor(props) {
  5.     this.spread = props
  6.     this.list = []
  7.     this.current = 0
  8.   }

  9.   do() {
  10.     this.list = this.list.slice(0, this.current + 1)
  11.     this.list.push(spreadToJSON(this.spread))
  12.     this.current = this.list.length - 1
  13.     console.log('this.list', this.list, this.current)
  14.   }

  15.   unDo() {
  16.     this.current--
  17.     if (this.current < 0) {
  18.       this.current = 0
  19.       return
  20.     }
  21.     this.setValue()
  22.   }

  23.   reDo() {
  24.     this.current++
  25.     if (this.current >= this.list.length) {
  26.       this.current = this.list.length - 1
  27.       return
  28.     }
  29.     this.setValue()
  30.   }

  31.   setValue() {
  32.     if (!this.list[this.current]) return
  33.     setTimeout(() => jsonToSpread(this.spread, this.list[this.current], true))
  34.     console.log('this.list', this.list)
  35.   }
  36. }
复制代码


// 初始化事件绑定
  1. function bindFns() {
  2.   const _this = this
  3.   this.contractEvent.addEvents('bindEvents', () => {
  4.     const commandManager = _this.spread.commandManager()
  5.     if (!commandManager.controlZ) {
  6.       // 重写 controlZ 和 controlY 和 EditEnded
  7.       _this.spread.commandManager().register('controlZ', () => {
  8.         _this.contractQueue.unDo()
  9.       })
  10.       _this.spread.commandManager().setShortcutKey('controlZ')

  11.       _this.spread.bind(GC.Spread.Sheets.Events.EditEnded, function (e, args) {
  12.         _this.contractQueue.do()
  13.       })

  14.       _this.spread.commandManager().register('controlY', () => {
  15.         _this.contractQueue.reDo()
  16.       })
  17.       _this.spread.commandManager().setShortcutKey('controlY')
  18.     }
  19.   })

  20.   this.contractEvent.triggerEvents('bindEvents')
  21. }
复制代码


将json更新到spread
  1. function jsonToSpread(spread, json, addIntoQueue=true) {
  2.   console.log('queue', queue)
  3.   json.sheets.Sheet1.columnCount = 100
  4.   console.log('jsonToSpread', json)
  5.   spread.fromJSON(json)
  6.   window.contractEvent.triggerEvents('bindEvents')
  7.   if (addIntoQueue) {
  8.     window.contractQueue.do()
  9.   }
  10. }
复制代码




评分

参与人数 1金币 +666 收起 理由
Lynn.Dou + 666 感谢分享,赞一个!

查看全部评分

回复 使用道具 举报
Lynn.Dou讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2021-7-23 09:40:36
推荐
抱歉前面理解有误,这边刚才跟研发讨论了下此问题,
fromJSON 之后实质是打开了新的spread,对于此spread来说是没有历史操作的,
所以undoManager 是空的。
目前没有可以满足您需求的方案。

您可以结合具体的业务情况详细的描述下为什么要实现此需求(业务场景)
这边报送研发调研看是否作为产品需求添加在之后的版本中。
回复 使用道具 举报
Lynn.Dou讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2021-7-22 18:38:43
沙发
您好,
SpreadJS v14支持获取撤销栈以及保留栈,
您参考下方资料了解详情,看能否满足您的需求。
https://demo.grapecity.com.cn/sp ... undo-manager/purejs
回复 使用道具 举报
马朝洋
注册会员   /  发表于:2021-7-23 09:10:35
板凳
Lynn.Dou 发表于 2021-7-22 18:38
您好,
SpreadJS v14支持获取撤销栈以及保留栈,
您参考下方资料了解详情,看能否满足您的需求。

stpred.fromJSON 之后,undoManager 里面的数据也没有了。不知道您说的可以满足物的需求是什么思路,能具体描述下嘛?
回复 使用道具 举报
马朝洋
注册会员   /  发表于:2021-7-23 09:52:05
5#
Lynn.Dou 发表于 2021-7-23 09:40
抱歉前面理解有误,这边刚才跟研发讨论了下此问题,
fromJSON 之后实质是打开了新的spread,对于此spread ...

需求:
客户需要对excel进行很多自定义的操作,比如对表格中的单元格上下拖拽,drop之后客户希望是可以将整行拖拽上去,需要在表格中插入多列并且将插入的单元格的数据都填充进去等等很多这种操作。

这种场景下使用fromJSON+ toJSON 直接对数据源进行更新是最灵活方便的。
但是现在发现,用了fromJSON之后历史操作无法使用了。您这边有什么好的思路嘛?
回复 使用道具 举报
Lynn.Dou讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2021-7-23 10:29:02
6#
这边试图理解您的需求,但看了您的描述后还是有很多疑问,
1、“对表格中的单元格上下拖拽” 这个指的是什么操作?表格指的是sheet还是table呢,可以结合截图来说明下吗?
2、“可以将整行拖拽上去”同上
3、“在表格中插入多列并且将插入的单元格的数据都填充进去”这里指的是插入的单元格的数据是如何填充的呢?
4、“使用fromJSON+ toJSON 直接对数据源进行更新是最灵活方便的”结合上述描述,在哪块进行了更新数据源呢
请详细的描述下。

前面有说过,fromJSON后,实质就是创建了新的spread,历史操作行为为空,目前没有办法实现此需求,您将需求描述清楚,这边会将此问题作为产品需求报送研发调研。
回复 使用道具 举报
马朝洋
注册会员   /  发表于:2021-7-23 10:46:34
7#
Lynn.Dou 发表于 2021-7-23 10:29
这边试图理解您的需求,但看了您的描述后还是有很多疑问,
1、“对表格中的单元格上下拖拽” 这个指的是什 ...

就是可以定制化很多操作,比如图1中将3,4行向上拖拽,然后实现整行的顺序调整。

图1:

1

1


图2:

2

2


回复 使用道具 举报
Lynn.Dou讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2021-7-23 11:13:43
8#
疑问1、2已了解,3、4可以说明下吗?
回复 使用道具 举报
马朝洋
注册会员   /  发表于:2021-7-23 15:32:46
9#
Lynn.Dou 发表于 2021-7-23 11:13
疑问1、2已了解,3、4可以说明下吗?

问题点和1,2 其实是一样的,核心需求是我想更灵活的操作表格,因为在你们这里 表格和json有个完整的映射关系,这个非常棒,基于此,直接对json做数据处理是一个更灵活更友好的处理方式。

基于这个模式我可以做多种多样的交互,而且不是限于你们提供的api。当然你们api已经很完善了,但是使用过程中还是有很多定制化的交互需求你们不能满足的。这时候json=》spread 的数据驱动视图的模式就会非常有帮助。可惜现在发现历史记录被清除掉了。

我建议你们做一个 fromStepJSON,可以对 原始数据的json和 传入的待更新的json做一个diff,然后依据这个diff结果 调用内置的一些api将视图更新进去。这不是一个严格意义上的fromJSON,因为没有生成新的spread,本质上只是通过diff调用一些内置的api,省去了去翻很多api文档到处都在调用api的麻烦。使用者只需要研究明白你们的json,其他的就尽在掌握了。

这样既能够让配置更灵活,又不会改动太多底层逻辑,还能保持历史记录。当然这是我的一个想法,还没有具体做,我后面试试看能不能行,或者您有更好的思路欢迎指教。

评分

参与人数 1金币 +200 收起 理由
Lynn.Dou + 200 感谢您的建议

查看全部评分

回复 使用道具 举报
Lynn.Dou讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2021-7-23 16:36:48
10#
感谢您细致的回复,这边会考虑您的建议,如果后续有计划添加此需求,会及时在贴中回复您。
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 立即注册
返回顶部