在企业级应用开发中,表格组件是数据展示与交互的核心载体。OneCode 平台自研的 Grid 表格组件,以模型驱动设计为核心,通过可视化配置与代码注解的深度融合,实现了从基础数据展示到复杂业务交互的全场景覆盖。本文将从功能特性、运行原理、注解配置及 DSM 领域建模管理四个维度,全面解析这款工业级表格组件的技术实现。
一、全场景覆盖的核心功能特性
1. 基础数据展示能力
- 智能列宽适配:支持AUTO(内容自适应)、FIXED(固定像素)、RATIO(百分比占比)三种模式,内置算法自动计算最小可见宽度,避免内容截断
- 多级表头设计:通过 JSON 结构定义多级嵌套表头,支持跨列合并(colspan)与跨行合并(rowspan),轻松实现复杂报表布局
- 数据格式化引擎:内置 20种常用格式器(日期 / 数字 / 金额 / 百分比),支持自定义 Java 函数或 JavaScript 表达式,例如:
@CustomAnnotation(caption="部门名称")
@GridColItemAnnotation(width="8.03em",flexSize=true)
public String getOrgName();
2. 交互式数据操作
- 单元格级编辑:支持输入框、下拉框、日期选择器等 16 种编辑组件,通过editorType属性快速切换,编辑事件支持双向数据绑定
- 批量操作工具条:内置全选 / 反选、批量删除 / 导出等 10 + 常用操作,支持自定义按钮组,配合@GridAction注解实现业务逻辑解耦
- 数据过滤与排序:表头自带筛选控件,支持多条件组合过滤,排序功能兼容后端分页与前端内存排序模式
3. 企业级增强功能
- 权限粒度控制:通过@GridPermission注解配置列级可见性、单元格编辑权限,支持与 Spring Security 集成实现 RBAC 控制
- 动态列配置:运行时可通过 API 新增 / 隐藏列,支持业务场景如 "用户自定义显示字段",配置信息自动持久化至元数据
- 大数据量优化:采用虚拟滚动技术(支持 10 万 + 数据量),配合懒加载分页组件,首屏渲染时间控制在 200ms 以内
二、分层架构与运行原理解析
1. 组件架构设计
2. 核心运行机制
(1)元数据驱动渲染
- 启动阶段:通过@GridAnnotation注解扫描实体类,结合 DSM 领域模型生成基础列配置
- 动态加载:支持从数据库 / 配置中心加载扩展元数据(如列别名、校验规则),实现 "模型 - 视图" 双向同步
- 缓存策略:采用 LRU 算法缓存高频使用的表格配置,元数据变更时通过 EventBus 触发视图重建
(2)事件响应体系
- 交互事件:封装 18 种基础事件(cellClick、rowDblClick、headerMenuClick),支持自定义事件扩展
- 防抖机制:对高频操作(如快速排序、滚动加载)实现 50ms 防抖处理,避免性能损耗
- 事务处理:编辑操作支持批量提交,通过@GridTransactional注解实现数据校验与回滚控制
(3)性能优化技术
- 虚拟滚动:仅渲染可见区域内的行(约 50 行),通过绝对定位模拟完整列表,内存占用降低 70%
- 懒加载策略:首屏加载时仅请求当前页数据,滚动至底部自动触发后续分页加载
- 增量渲染:数据变更时通过 Diff 算法计算最小更新范围,避免全量重绘
三、注解驱动的灵活配置体系
一、Grid相关注解
1. @GridAnnotation
作用范围:类级别注解,用于定义表格组件的整体配置
属性说明:
属性名 | 类型 | 默认值 | 描述 |
customMenu | GridMenu[] | {} | 自定义菜单选项 |
bottombarMenu | GridMenu[] | {} | 底部工具栏菜单 |
event | CustomGridEvent[] | {} | 绑定的表格事件 |
isFormField | boolean | true | 是否作为表单字段 |
togglePlaceholder | boolean | true | 是否显示切换占位符 |
directInput | boolean | true | 是否允许直接输入 |
rowResizer | boolean | false | 是否允许行高调整 |
colResizer | boolean | true | 是否允许列宽调整 |
colSortable | boolean | true | 是否允许列排序 |
altRowsBg | boolean | true | 是否显示交替行背景色 |
showHeader | boolean | true | 是否显示表头 |
dock | Dock | Dock.fill | 表格停靠方式 |
uidColumn | String | “” | UID列名 |
valueSeparator | String | “;” | 值分隔符 |
rowHeight | String | “3.0em” | 行高 |
bindTypes | ComponentType[] | {ComponentType.TreeGrid} | 绑定的组件类型 |
2. @GridColItemAnnotation
作用范围:字段或方法级别注解,用于定义表格列的具体属性
属性说明:
属性名 | 类型 | 默认值 | 描述 |
title | String | “” | 列标题 |
width | String | “8em” | 列宽度 |
editable | boolean | false | 是否可编辑 |
enumClass | Class<? extends Enum> | Enum.class | 枚举类 |
inputType | ComboInputType | ComboInputType.input | 输入框类型 |
flexSize | boolean | false | 是否启用弹性尺寸 |
headerStyle | String | “” | 表头样式 |
colResizer | boolean | false | 是否允许列宽调整 |
3. @GridEvent
作用范围:方法、字段或类级别,用于绑定表格事件处理逻辑
属性说明:
属性名 | 类型 | 默认值 | 描述 |
eventEnum | GridEventEnum | - | 事件枚举类型,如onClickGridHandler、beforeGridValueCalculated等 |
expression | String | “true” | 事件触发条件表达式 |
customActions | CustomGridAction[] | {} | 自定义操作集合 |
actions | CustomAction[] | {} | 关联的操作 |
event | CustomGridEvent[] | {} | 自定义事件类型 |
二、Grid相关枚举
1. GridMenu枚举
描述:定义表格支持的菜单操作类型
枚举值:
- Add: 添加操作
- Delete: 删除操作
- Reload: 刷新操作
- Sort: 排序操作
- Filter: 筛选操作
- Export: 导出操作
- Import: 导入操作
- Print: 打印操作
2. CustomGridAction枚举
描述:定义表格支持的自定义操作类型
枚举值:
- Delete: 删除操作
- Reload: 刷新操作
- Save: 保存操作
- SortUP: 升序排序
- SortDown: 降序排序
- AddRow: 添加行
- DeleteRow: 删除行
- LoadMenu: 加载菜单
3. GridEventEnum枚举
描述:定义表格支持的事件类型
枚举值:
- onClickGridHandler: 表格点击事件
- beforeGridValueCalculated: 表格值计算前事件
- afterGridValueCalculated: 表格值计算后事件
- onRowClick: 行点击事件
- onRowDblClick: 行双击事件
- onHeaderClick: 表头点击事件
4. GridRowMenu枚举
描述:定义表格行菜单操作类型
枚举值:
- View: 查看操作
- Edit: 编辑操作
- Delete: 删除操作
- Copy: 复制操作
- Export: 导出操作
5. GridColItemAnnotation相关枚举
ComboInputType:
- input: 文本输入框
- select: 下拉选择框
- radio: 单选按钮组
- checkbox: 复选框组
- date: 日期选择器
代码示例
// 表格定义示例
@GridAnnotation(
customMenu = {GridMenu.Add, GridMenu.Delete},
event = {CustomGridEvent.editor, CustomGridEvent.sort},
dock = Dock.fill,
rowHeight = "3.5em"
)
public class UserGridViewBean extends CustomGridViewBean {
// 表格实现
}
// 列属性配置示例
public class UserInfoBean {
@GridColItemAnnotation(title = "用户名", width = "12em", editable = true)
private String userName;
@GridColItemAnnotation(title = "状态", enumClass = StatusEnum.class, inputType = ComboInputType.select)
private String status;
}
3. 配置优先级规则
- 方法级注解 > 字段级注解 > 类级注解
- 代码注解 > DSM 可视化配置 > 默认全局配置
- 运行时动态配置(API 方式)覆盖所有静态配置
四、DSM 领域建模工具深度集成
一,列表视图组成
列表视图,主要由两部分来组成,领域服务主要负责,实体相关属性以及路由动作相关的操作。由领域设计完成相关的应用。
列表视图组成
展示样例
二,领域功能分解
视图配置是本文主要讲解的部分,在列表配置中,主要由模块配置和子域配置两个部分组成。
视图配置组成
三,视图模块配置
(1)视图模块配置概览
主要负责列表视图的基本属性配置以及跟业务想相关的操作动作配置。
模块配置
(2) 环境变量设置:
在模块构建时通常是在特定环境下运行的,这些特性环境一般是由,聚合实体以及聚合跟的组件值配合当前用户等环境值对象来完成。在列表视图中如果需要添加环境变量,只需要在视图类中添加。
相应的 聚合KEY 并且在字段上添加@Pid,或者@Uid (参考下面具体示例),Uid 代表当前实体的组件值。Pid则是来自于父级以及环境变量值。添加注解后,OneCode解析器会自动关联当前环境并在运行时进行赋值。
常用注解示例
注解名称 | 用途 | 示例 |
@Pid | 环境变量,父级全局 | @Pid |
@Uid | 环境变量,当前主键 | @Uid |
@CustomAnnotation | 自定义隐藏域 | @CustomAnnotation(hidden = true) |
配置界面
(3) 列表视图配置:
视图配置主要是列表本身以及其相关操作栏的设定。
分页栏配置
工具栏配置
工具栏
模块底部按钮栏
常用注解示例
注解名称 | 用途 | 示例 |
GridAnnotation | 列表视图配置 | @GridAnnotation(rowHeight = "4em", customService = {LocalFormulaService.class}, event = CustomGridEvent.editor) |
PageBar | 分页栏 | @PageBar(pageCount = 100) |
ToolBarMenu | 工具栏 | @ToolBarMenu |
MenuBarMenu | 菜单栏 | @MenuBarMenu |
BottomBarMenu | 底部工具栏 | @BottomBarMenu |
四,视图子域
(1)视图子域概览
在实际应用中,列表通常是以独立的模块来呈现,但在用户在操作时会涉及到操作行甚至操作到表格应用。
(2)行集子域
行子域概览
在行集域属性配置时,通常会根据数据实体的域事件来匹配相关的功能按钮。如:实体操作中,常见的CRUD事件,则会自动在行按钮上匹配上删除图标,在行头设定上启动,增加行标记。如果记录集允许弹出编辑这会对应添加双击编辑事件。
域属性图
行域操作
实际表格域划分示例
常用事件添加管理
注解名称 | 用途 | 实例 |
@GridRowCmd | 表格行按钮 | @GridRowCmd(tagCmdsAlign = TagCmdsAlign.left, menuClass = {DBColAction.class}) |
@RowHead | 行头配置 | @RowHead(selMode = SelModeType.none, gridHandlerCaption = "删除|排序", rowHandlerWidth = "10em", rowNumbered = false) |
@PageBar(pageCount = 100)
@RowHead(selMode = SelModeType.none, gridHandlerCaption = "删除|排序", rowHandlerWidth = "10em", rowNumbered = false)
@GridRowCmd(tagCmdsAlign = TagCmdsAlign.left, menuClass = {DBColAction.class})
@GridAnnotation(customService = {ColService.class}, customMenu = {GridMenu.Reload, GridMenu.Add}, event = CustomGridEvent.editor)
public class DbColGridView {
@CustomAnnotation(caption = "字段名", uid = true, required = true)
private String name;
@CustomAnnotation(caption = "类型", required = true)
private ColType type = ColType.VARCHAR;
@CustomAnnotation(caption = "长度", required = true)
private Integer length = 20;
@CustomAnnotation(caption = "数字精度")
private Integer fractions = 0;
@CustomAnnotation(caption = "是否主键")
private Boolean pk;
@CustomAnnotation(caption = "是否可为空")
private Boolean canNull = true;
@CustomAnnotation(colSpan = -1, caption = "注解", rowHeight = "100", required = true)
private String cnname;
}
(3)单元格子域
当表格属性设置为可以编辑域时,列表会以列为单位转换位,列表表单视图。单元格应用更多的会涉及到表单的相关操作,会在后续表单章节中做近一步的介绍。
单元格编辑
单元格类型
五、最佳实践:复杂表格场景实现
案例:供应链订单管理表格
需求:
- 显示 30 + 字段,支持列自由拖拽排序
- 金额列自动千位分隔,带红色警示(低于成本价)
- 状态列支持下拉框编辑,关联 ERP 系统字典
- 行级权限控制(不同部门只能编辑自己创建的订单)
实现方案:
- 列配置:使用@GridColItemAnnotation(draggable=true)开启列拖拽,通过formatter实现金额格式化
- 样式控制:自定义cellStyle函数,根据数据值动态设置字体颜色
- 数据联动:@GridAction(options = "http://erp-api/dict/status")实现动态下拉框
- 权限控制:通过@PreAuthorize结合@GridPermission实现行级可见性过滤
六、总结与生态建设
OneCode Grid 表格组件通过注解驱动 + 元数据管理 + 可视化建模的三维架构,实现了从简单列表到复杂数据中台的全场景覆盖。其核心价值在于:
- 开发效率:减少 70% 的表格代码编写量,配置即开发
- 一致性:通过 DSM 实现设计 - 开发 - 运行时的配置统一
- 扩展性:开放的插件机制支持快速集成第三方组件