简介: 在前端可视化搭建领域中“重做”和“撤销”这两个功能已经是标配中的标配,毕竟只要有用户行为的地方就可能会有出错,这两个功能无疑就是为用户提供了“后悔药”。目前有各种各样的可视化搭建平台,本文介绍IoT Studio可视化搭建平台在编辑历史功能上的设计与思考。

作者 | 远坂
来源 | 阿里技术公众号

一 背景

在前端可视化搭建领域中“重做”和“撤销”这两个功能已经是标配中的标配,毕竟只要有用户行为的地方就可能会有出错,这两个功能无疑就是为用户提供了“后悔药”。目前有各种各样的可视化搭建平台,本文介绍IoT Studio可视化搭建平台在编辑历史功能上的设计与思考。

二 实现思路

1 页面DSL的维护

在IoT Studio可视化搭建平台中,我们通过页面的抽象语法树来维护页面状态,页面信息和组件信息都记录在对应节点上:

PageNode: {componentName: 'page1',id: 'page1',props: {},children: [ComponentNode: {componentName: 'component1',id: 'component1',props: {width: 800,height: 1000,color: '#ffffff'},children: []},ComponentNode: {componentName: 'component2',id: 'component2',props: {},children: []},ComponentNode: {componentName: 'component3',id: 'component3',props: {},children: []},]
}

在页面保存时,页面配置会作为JSON文件上传至OSS。

2 重做与撤销

快照法

在每次编辑页面时,将页面的信息进行深拷贝存入历史记录中。在进行重做和撤销时从历史记录中取出对应的快照,用快照代替当前页面状态,即可完成一次历史记录的操作。

在这种方法下,通常使用一个指针来指向当前的页面状态。如下图:

进行后退操作后,指针指向之前的某次快照,页面恢复到P3时的状态:

再次进行编辑时,指针指向新的状态P5 :

快照法的特点:

  1. 实现比较简单,页面信息全量进行深拷贝即可。
  2. 历史记录之间的切换灵活。
  3. 当页面信息很大时,十分占用存储空间。

指令法

IoT Studio使用的是这种方法。

我们为每一次操作定义两个方法:execute与undo,以及将“操作”抽象为Operation。

在execute中执行这次操作的正向操作,在undo中实现逆向操作。

export abstract class Operation<T = void> {  /*** 逆向操作*/protected abstract undo(): T;/*** 正向操作*/protected abstract execute(): T;
}

每进行一次编辑操作,其实就是创建一次Operation并执行其execute方法,随后如果需要撤销就执行其undo方法。

指令法的特点:

  1. 相对快照法,在页面配置复杂时,能节省不少存储空间。
  2. 不同的Operation其execute和undo逻辑很可能会不一样,有一定的逻辑开发成本。
  3. 跨多个历史记录的重做或撤销,需要执行他们之前所有的execute或undo。例如,上图中如果从O3到O1需要执行2次undo。这一点没有快照法便利。

3 实现细节

在上文里提到了IoT Studio使用的是指令法。

Transation

在实际业务开发中,很多场景会涉及到一次性编辑多个组件,即涉及多个Operation实例。于是在Operation基础上有了Transaction——事务的概念,Transaction下维护了一份Operation实例List,每当有execute或者undo执行时,会遍历Operation List中的Operation实例执行其execute或undo方法。

双向链表

IoT Studio中的操作历史是基于双向链表实现的,每个链表节点维护一个Transaction实例。链表节点末端的execute结果既是最新的操作历史。

链表之前通过forwardCurrent和backforwardCurrent方法进行节点状态的切换。

Class Manager {backwardCurrent(): boolean {if (this._current?.prev) {this._current.value.operation.undo();this._current = this._current.prev;this._validLength -= 1;return true;}return false;}forwardCurrent(): boolean {if (this._current?.next) {this._current.next.value.operation.execute();this._current = this._current.next;this._validLength += 1;return true;}return false;}addAfterCurrent(item: OperationResult<any>) {if (nextNode) {nextNode.prev = undefined;this._length = this._validLength;}this._current.next = { value, prev: this._current };this._current = this._current.next;}
}

每当有新的编辑操作时,会通过addAfterCurrent插入新的节点。

4 总结

Operation是实现重做和撤销的最小指令实例,通过Operation不同子类实现不同的execute和undo方法,从而实现重做和撤销的具体逻辑。

Transaction中维护了Operation实例数组,我们在进行业务逻辑开发中对组件进行属性设置时是以Transaction实例为单位进行业务逻辑开发。

维护了一个双向链表来对Transaction实例进行管理,从而实现可视化搭建的操作历史功能。

三 探索

在实现思路中我们提到了“快照法”和“指令法”,对比两者的优缺点,不难发现主要矛盾是在体积与维护成本上。那么有没有一种办法能兼顾二者的优点呢?下面两个工具可以提供一些思路:

immutable.js + 快照法

在JS中对象是引用赋值,在保存对象时往往会使用深拷贝规避这个问题,但是这样会造成CPU和内存的浪费,这也是快照法的缺点所在。

immutable使用持久化数据结构,在使用旧数据创建新数据的时候,会保证旧数据同时可用且不变,同时为了避免深度复制复制所有节点的带来的性能损耗,immutable使用了结构共享,即如果对象树种的一个节点发生变化,只修改这个节点和受他影响的父节点,其他节点则共享。

在实现操作历史功能时,使用immutable存储数据,能解决数据复用的问题。immutable.js + 快照法可以组合使用。据我所知公司的@ali/visualengine使用的就是这个方案。

Git

每次我们运行 git add 和 git commit 命令时,Git 所做的工作实质就是将被改写的文件保存为数据对象, 更新暂存区,记录树对象。

我们在使用git维护项目时,理论上随着git commit的次数越来越多,文件对象会越拉越大,但实际上体积并没有变的很大。事实上git在权衡时间和空间后帮我们做了部分优化,较早的版本会保存diff,较新的本会保存全量数据对象。

Git 是如何做到这点的?Git 打包对象时,会查找命名及大小相近的文件,并只保存文件不同版本之间的差异内容。 你可以查看包文件,观察它是如何节省空间的。
同样有趣的地方在于,第二个版本完整保存了文件内容,而原始的版本反而是以差异方式保存的——这是因为大部分情况下需要快速访问文件的最新版本。最妙之处是你可以随时重新打包。Git 时常会自动对仓库进行重新打包以节省空间。当然你也可以随时手动执行 git gc 命令来这么做。

原文链接

本文为阿里云原创内容,未经允许不得转载。

IoT Studio可视化搭建平台编辑历史功能的思考与探索相关推荐

  1. 可视化搭建平台的地图组件和日历组件方案选型

    可视化搭建平台除了需要为用户提供简单便捷的操作方式之外, 还需要提供丰富的组件支持和组件扩展, 这样才能满足更多用户的业务需求. 在 H5-dooring 创建的初期主要考虑的方向是用户使用的便捷性, ...

  2. 如何设计可视化搭建平台的组件商店?

    相关文章: 如何搭积木式的快速开发H5页面? 演示地址: H5-Dooring页面制作平台 关注并将「趣谈前端」设为星标 每早08:30按时推送技术干货/优秀开源/技术思维 之前一直在做 lowcod ...

  3. 深度解析大数据可视化管理平台的监控功能

    在上一篇的文章中已经明确说过DKM作为大快发行版DKhadoop的管理平台,它的四大功能分别是:管理功能,监控功能,诊断功能和集成功能.管理功能已经给大家列举了一些做了说明,今天就DKM平台的监控功能 ...

  4. 「可视化搭建系统」——从设计到架构,探索前端领域技术和业务价值

    阿里巴巴集团前端委员会主席 圆心:未来前端的机会在哪里 对前端未来期许有四点:搭建服务, Serverless,智能化,IDE.仔细想想,一个「可视化搭建系统」的想象空间,正能完美命中这些方面.前端的 ...

  5. H5-Dooring可视化搭建平台的新技能

    H5-Dooring在持续更新迭代中, 接下来笔者将带大家介绍一下H5-Dooring的新功能, 并介绍网格参考线的实现方案, 内容很短, 实现方案也很简单, 欢迎大家提出更好的方案和实现思路. 最近 ...

  6. 可视化搭建平台的参考网格线设计

    最近一工作一直很忙, H5-Dooring也在持续更新迭代中, 接下来笔者将带大家介绍一下H5-Dooring的新功能, 并介绍网格参考线的实现方案, 内容很短, 实现方案也很简单, 欢迎大家提出更好 ...

  7. 计算机组成原理:循环冗余校验码CRC具备“一位纠错”功能的思考与探索

    笔者在阅读华中科技大学谭志虎老师主编的<计算机组成原理(微课版)>教材进行复习时,产生了一个疑问,并针对性地进行了一些思考.欢迎广大复习到这里同样有问题的同学(寒假开学接着考试实在有点汗, ...

  8. 移动端实现元素拖拽效果插件_基于自然流布局的可视化拖拽搭建平台设计方案...

    LowCode 是高效.高性能的拖拽式低代码开发平台. 也是笔者最近一直在研究的方向, 对于可视化搭建平台的实现方案笔者之前写过很多文章, 这里带大家探索一个新方向--基于自然流布局的可视化搭建平台. ...

  9. 基于自然流布局的可视化拖拽搭建平台设计方案

    LowCode 是高效.高性能的拖拽式低代码开发平台. 也是笔者最近一直在研究的方向, 对于可视化搭建平台的实现方案笔者之前写过很多文章, 这里带大家探索一个新方向--基于自然流布局的可视化搭建平台. ...

最新文章

  1. 组织可以最大限度提高数据中心性能的五个步骤
  2. 最新Angular2案例rebirth开源
  3. .NET Core实战项目之CMS 第十一章 开发篇-数据库生成及实体代码生成器开发
  4. mysql权限表_MySQL 数据库赋予用户权限操作表
  5. oracle模糊查询很慢,采用全文索引解决模糊查询速度慢的问题
  6. OpenWrt的UCI系统
  7. Bootstrap CSS 编码规范之Class 命名规范
  8. VB Environ系统环境变量函数大全
  9. 别以为真懂Openstack: 虚拟机创建的50个步骤和100个知识点(1)
  10. 【译文】Nodejs官方文档(Part 3 断言测试)
  11. 批量删除 Excel 工作薄文档中的工作表
  12. GWAS 总体流程理解版
  13. 简书CEO 林立:简书钻改,让付出有所得
  14. Python自定义一个异常类【注释详细】
  15. 困惑了很久的函数D3DXCreateTextureFromFileInMemoryEx
  16. 现实题材网络文学正打开广阔天地
  17. React Native 中的 Android 原生模块
  18. 计算机一级考试文字处理题知识
  19. DPLink: User Identity Linkage via Deep Neural Network From Heterogeneous Mobility Data 阅读笔记
  20. POI Excel 上下标、下划线、粗体、斜体标签处理(sup、sub、u、strong、em的HTML标签转化到excel格式)①

热门文章

  1. JAVA入门级教学之(成员内部类)
  2. sql 删除最低分数_软件测试从业者:必备SQL语句21天打卡,前10天
  3. python递归_python3之递归
  4. python open写入_Python3 open() 函数详解 读取文件写入文件追加文件二进制文件
  5. 鸿蒙系统打通iOS,库克真的做到了!正式官宣确认截胡鸿蒙OS系统:软硬件生态全打通...
  6. pythondistutils安装_python – 与distutils / pip一起安装Bash完成
  7. mac adb 找不到设备_win/Mac办公软件下载找不到资源?试试这三个强大的神器
  8. vba 删除 添加checkbox_如何设置EXCEL输入内容后自动添加边框?
  9. 抓狐狸python_​用Python操作Kubernetes的Job
  10. java 如何导出json文件_java导出json格式文件的示例代码