alibaba / formily

📱🚀 🧩 Cross Device & High Performance Normal Form/Dynamic(JSON Schema) Form/Form Builder -- Support React/React Native/Vue 2/Vue 3
https://formilyjs.org/
MIT License
11.43k stars 1.49k forks source link

关于如何动态设置表格列属性? #1002

Closed NexxLuo closed 4 years ago

NexxLuo commented 4 years ago

表格是表单中很重要的一部分,但是目前表格无法很好的动态设置列的属性,比如设置列宽、冻结、标题等。

我理解的实现方式有以下几种:

  1. 直接操作Schema ; 简单粗暴,但会导致Form整体的render;
  2. 把表格列头作为一个VirtualField渲染出来;这样只能解决title的动态问题,例如列宽之类的依然无法设置
  3. 直接通过x-component-props.columns托管表格列;这样可以完全控制表格的列配置,但却改变了原有的schema结构
  4. 如果formily能够提供一个修改局部schema的方式,我觉得会是比较合理的。比如添加一个类似setFieldState的方法 setFieldSchema

目前我还找不到特别好的方式,求各位答疑,thanks

zhangwilling commented 4 years ago

最近在深入研究和使用,以下是一点见解。

首先,schema 这块本身没有 dirty check 的(内核 field 是有的,可能就让你觉得不一致,有点不对劲)。看下 SchemaField 那边的实现,props 几乎都是新对象,schema 也都是new 出来的,因此即使 memo(Field) 了也很难起作用,所以改动基本就是全量渲染。

针对你的场景:

我觉得你的3 是相对比较好的方案,可以归纳说是一种局部自治的方案。初次渲染后基本骨架已经 ok,后续的动作都是局部的动作,个人觉得不需要同步到 schema 中去。

回到你的担心上:不一致的问题。怎么办?可以去同步合并到全局的 schema 里去,但似乎又会遇到全量渲染的问题。

下一步,用什么样的同步的策略怎样才能减少全量渲染的代价?

其实,到这里都能想到技术的解决方案了 。比如,debouced 全量渲染 或者 某种触发器机制渲染 (这里更偏向一种优化策略)

具体一些,在 schema 需要持久化的场景里(比如下次打开编辑时还原上次操作这种场景),可以通过一个用户的 save 动作触发合并进全局的 schema ,再提交给服务端。

NexxLuo commented 4 years ago

在钉钉群里收到了@鬼鼠大佬的回复,https://alist.wiki/#/BZfYfW/aQFaFQte, 所有不能设置的属性都能通过VirtualBox来解决。

目前我的处理方式是给Table的state.props中注入了setColumns方法供外部调用。

zhangwilling commented 4 years ago

我们是用 antd-pro 还有 antd 加 UED 二次设计封装的 😁 。AList 一直没发现,看起来不错,推荐一波。