〖领码方案〗前端 PageData 完整解决方案 第四版
〖领码方案〗前端 PageData 完整解决方案 第四版
关键字:PageData架构 · BindingContext · dependencyType · JSON过滤表达式 · DataRelation · 低代码平台
1. 引言:背景与痛点
在复杂的 SPA 前端应用中,数据管理是核心难题。
传统 DataSet 模型启发了 PageData 的设计,但在同一张表同时绑定多个组件时,currentRow
、selectedRows
往往会产生混乱。
第三版虽然引入了 BindingContext 概念,但仍有三大痛点:
- 手动 index 编号冗余且易冲突
- 固定 relationType 缺乏业务语义
- filterExpression 难以跨 SQL、MongoDB 和内存统一解析
第四版应运而生,彻底解决上述问题。
2. 核心改进
-
默认上下文
- DataTable 继承 BindingContext,天然拥有
componentID
、currentRow
、selectedRows
。 - 大多数场景无需再配置 contexts 数组。
- DataTable 继承 BindingContext,天然拥有
-
依赖类型(dependencyType)
- 用业务语义表达父子数据依赖范围:
currentRow
/selectedRows
/allRows
/ 自定义。 - 支持未来扩展
pagedRows
、filteredRows
等。
- 用业务语义表达父子数据依赖范围:
-
通用 JSON 过滤表达式(filterExpression)
- 采用节点树结构,支持条件、逻辑组合、取反、函数调用。
- 可生成 SQL WHERE、MongoDB 查询对象、内存 Array.filter 回调。
-
零编号配置
- 上下文序号由系统自动分配,DataRelation 中缺省序号即指默认上下文。
3. 架构流程图
4. TypeScript 接口定义(逐行中文注释)
// 将每一行数据表示成键值对结构
export type DataRow<T = any> = Record<string, T>; // 一行数据记录// 定义绑定上下文,包含组件绑定和选中状态
export interface BindingContext {componentID?: string; // 绑定组件的唯一标识currentRow?: DataRow; // 当前选中行selectedRows?: DataRow[]; // 批量选中行集合
}// 列定义:描述表中每个字段的元数据
export interface DataColumn {columnName: string; // 字段名称,必须唯一dataType: string; // 数据类型,如 'string'、'number'allowDBNull?: boolean; // 是否允许空值defaultValue?: any; // 默认值isPrimaryKey?: boolean; // 是否主键autoIncrement?: boolean; // 是否自增
}// HTTP 端点定义:描述单个 API 调用的属性
export interface HttpEndpoint {url: string; // 接口地址method?: 'GET'|'POST'|'PUT'|'PATCH'|'DELETE';// HTTP 方法headers?: Record<string, string>; // 请求头queryParams?: Record<string, unknown>; // URL 查询参数pathParams?: string[]; // 路由参数列表bodySchema?: unknown; // 请求体结构(可选)
}// CRUD API 组:一组增删改查及导入导出接口
export interface CrudApi {create?: HttpEndpoint; // 新增接口retrieve?: HttpEndpoint; // 查询单条接口update?: HttpEndpoint; // 更新接口delete?: HttpEndpoint; // 删除接口list?: HttpEndpoint & { // 列表接口pagination?: { // 分页参数配置pageParam?: string; // 页码参数名sizeParam?: string; // 页大小参数名sortParam?: string; // 排序参数名};};batch?: { // 批量操作create?: HttpEndpoint; // 批量新增update?: HttpEndpoint; // 批量更新delete?: HttpEndpoint; // 批量删除};import?: HttpEndpoint; // 导入接口export?: HttpEndpoint; // 导出接口
}// DataTable 继承 BindingContext:表自带默认上下文
export interface DataTable extends BindingContext {tableName: string; // 表名columns: DataColumn[]; // 字段定义列表api?: CrudApi; // 可选 CRUD 接口组rows: DataRow[]; // 数据行集合contexts?: BindingContext[]; // 额外上下文集合(多视图绑定)
}// 依赖类型:当前行 / 选中行 / 全部行 / 可自定义扩展
export type DependencyType =| 'currentRow' // 依赖父上下文的 currentRow| 'selectedRows' // 依赖父上下文的 selectedRows| 'allRows' // 依赖父上下文的全部行| string; // 预留自定义类型// 通用 JSON 过滤表达式节点定义
export type FilterExpression =| { field: string; op: string; value: any } // 单一条件节点| { type: 'and' | 'or'; children: FilterExpression[] } // 与 / 或 逻辑组合| { type: '!condition'; field: string; op: string; value: any }// 条件取反| { type: '!and' | '!or'; children: FilterExpression[] } // 逻辑取反组合| { func: string; args: any[] } // 函数调用节点// DataRelation:父子表关系配置
export interface DataRelation {parentTable: string; // 父表名parentContextOrder?: number; // 父上下文序号,缺省表示默认上下文childTable: string; // 子表名childContextOrder?: number; // 子上下文序号,缺省表示默认上下文dependencyType: DependencyType; // 依赖类型filterExpression: FilterExpression;// 通用 JSON 过滤表达式cascadeUpdate?: boolean; // 是否级联更新cascadeDelete?: boolean; // 是否级联删除
}// DataSet:整体数据集管理
export interface DataSet {dataSetName: string; // 数据集名称tables: DataTable[]; // 所有表定义relations?: DataRelation[];// 可选关系配置version?: number; // 版本号,用于热加载或迁移
}
5. 使用示例
// 定义用户表
const users: DataTable = {tableName: 'Users',columns: [{ columnName: 'id', dataType: 'number', isPrimaryKey: true },{ columnName: 'name', dataType: 'string' }],rows: [{ id: 1, name: 'Alice' },{ id: 2, name: 'Bob' }]
};// 定义订单表
const orders: DataTable = {tableName: 'Orders',columns: [{ columnName: 'id', dataType: 'number', isPrimaryKey: true },{ columnName: 'userId', dataType: 'number' },{ columnName: 'amount', dataType: 'number' }],rows: [{ id: 101, userId: 1, amount: 200 },{ id: 102, userId: 2, amount: 150 }]
};// 组装 DataSet
const dataSet: DataSet = {dataSetName: 'AppDataSet',tables: [users, orders],relations: [{parentTable: 'Users',childTable: 'Orders',dependencyType: 'currentRow',filterExpression: {field: 'userId',op: '==',value: { func: 'FIELD', args: ['id'] }}}]
};// 模拟选中用户 Alice
users.currentRow = users.rows[0];// 根据 relations 过滤订单
orders.selectedRows = orders.rows.filter(row =>row.userId === users.currentRow!.id
);console.log(orders.selectedRows);
// 输出 Alice 的订单:[{ id: 101, userId: 1, amount: 200 }]
6. 架构优势
- 简洁:默认上下文 + 自动编号,极大减少配置量
- 语义化:dependencyType 直接表达业务依赖范围
- 跨库统一:filterExpression 一次配置,多端解析
- 低代码友好:天然适配可视化关系设计器
7. 下一步建议
- 实现 FilterExpression 解析器,可输出 SQL
WHERE
、MongoDB 查询对象和内存filter
函数 - 构建 BindingContextManager,统一管理上下文生命周期与自动编号
- 在低代码平台集成 可视化关系编辑器,拖拽式配置 dependencyType 和 JSON 表达式
- 提供示例项目与在线文档,帮助业务团队快速上手
8. 完整性评估
8.1 核心功能覆盖情况
-
接口定义
全面涵盖 DataRow、BindingContext、DataColumn、HttpEndpoint、CrudApi、DataTable、DependencyType、FilterExpression、DataRelation、DataSet 等核心模型。 -
架构流程
提供了从“加载配置 → 自动编号 → 解析关系”到“渲染组件 → 触发依赖 → 过滤子数据 → 更新上下文 → 重渲染”的完整流程图。 -
使用示例
通过用户表与订单表示例演示 DataSet 配置、dependencyType 与 JSON filterExpression 的运行时效果。 -
可视化设计
明确指向可视化关系编辑器的思路,但尚未给出 UI 插件层面实现。
8.2 评估维度与覆盖矩阵
评估维度 | 覆盖情况 | 说明 |
---|---|---|
接口定义完整性 | ✔️ | 涵盖所有模块与字段,注释详实 |
架构流程描述 | ✔️ | 初始化与运行时各环节清晰可见 |
代码示例可行性 | ✔️ | 示例完整、可直接运行 |
可扩展性设计 | ✔️ | 支持自定义依赖类型与函数节点 |
运行时实现细节 | ⚠️ | 未提供 FilterExpression 解析器或上下文管理器的示例 |
可视化工具集成 | ⚠️ | 提及关系编辑器,但缺少 API 或 UI 插件层面的集成方案 |
性能与安全 | ⚠️ | 未讨论跨库查询性能优化、权限控制、输入校验与防注入策略 |
文档与迁移支持 | ⚠️ | 建议增加从第三版到第四版的迁移指南、完整 API 参考手册 |
8.3 改进建议
-
FilterExpression 解析器
完整实现一套运行时模块,将 JSON 节点映射到 SQL WHERE、Mongo 查询对象和Array.filter
回调。 -
BindingContextManager
提供自动编号、上下文生命周期管理、事件订阅机制以及内存回收支持。 -
可视化关系编辑器
基于依赖类型与 JSON 表达式设计拖拽式 UI,输出符合接口定义的配置 JSON。 -
性能与安全机制
增加对大数据集分页、惰性加载、异步流控的支持;
在 filterExpression 输入中加入语法校验与注入防护。 -
文档与迁移指南
补充从第三版到第四版的升级对照表;
提供完整的接口参考文档、示例仓库与常见问题解答。
8.4 结论
第四版 PageData 在模型完整性、业务语义表达和跨库统一过滤方面达到非常高的覆盖度。
为进一步提升可落地性和平台级稳定性,建议尽快补充运行时解析器、上下文管理器、可视化编辑集成以及性能安全策略,并完善配套文档与迁移支持。
整体来看,这套方案已具备生产级应用的核心能力,只待少量补充与工具化,便能真正成为低代码与传统 SPA 的基础数据管理平台。