Skip to content

Classic Form 与 Responsive Form

Form 决定 Item 的字段如何呈现和交互;View 决定在某个上下文中选用哪个 Form。Property、Form Field 和 Permission 是三层不同的东西:有数据字段不代表表单会显示,表单禁用也不代表服务器拒绝修改。

本章为 acme_equipment 准备一个可以新建和编辑的表单。

版本范围

  • R31 原厂配置培训同时覆盖 Classic Form 和 Responsive Form。
  • 官方版本资料将 R28 标为 Responsive Forms preview、R29 标为首次正式发布,R30 又加入条件逻辑;更早版本可能没有这套表单能力,后续版本的编辑器也会继续变化。
  • R35 Responsive Forms Guide 明确:Responsive Form 只支持 Default View;Add、Edit、View、Print、Complete、Preview 等特定 View 仍使用 Classic Form。其他 Release 也要查同版本限制。
  • 用户提供的大量 document.thisItem、frame 和 DOM 代码属于 Classic Client 兼容内容,必须按具体 Release 测试。

先选择表单类型

维度Classic FormResponsive Form
布局方式传统坐标/固定布局能力较多响应式行列布局
旧客户端 Method 兼容较高,但常依赖旧上下文不应假定可直接复用
多尺寸适配需要额外设计设计目标就是响应式
适用场景维护既有表单、强版本绑定定制、非 Default View新建现代 Default View

如果项目已经有大量经过验证的 Classic 定制,可以逐步治理;新建表单则优先评估目标 Release 的 Responsive Form 能否满足需求。

目标布局

text
设备信息
├─ 设备编号       型号
├─ 设备名称       设备类型
└─ 投产日期       启用

表单只解决录入体验。编号唯一性、必填、权限和状态限制仍要在数据模型和服务端验证。

第 1 步:确认 View 绑定

  1. 打开 acme_equipment 的 Views 配置。
  2. 确认目标 Form 与该 ItemType 关联。
  3. 明确它用于 Default 还是其他 View;在 R35 中,非 Default View 必须使用 Classic Form。
  4. 保存前记录原有 View,避免把正在使用的生产表单替换掉。

多个 View 同时匹配时的选择规则可能受版本和配置影响。不要凭一份旧培训材料写死优先级;应在目标环境用两种身份和两条分类数据验证。

第 2 步:构建 Responsive Form

以 R35 官方流程为例:

  1. 在 ItemType 的 Views 中执行 New Form;新 Form 会先以 Classic definition 创建。
  2. 打开该 Form,执行 Switch to Responsive Form,生成独立且初始为空的 Responsive definition;Classic 布局不会自动迁移。
  3. 创建一个“设备信息”区域。
  4. 使用两列布局放置编号、名称、型号、设备类型、投产日期和启用状态。
  5. 为窄屏配置合理的列折叠/换行行为。
  6. 保存并重新打开编辑器,确认布局持久化。
  7. 将 Form 绑定到 Default View;R35 不支持把 Responsive Form 用作 Add/Edit/View/Print/Complete/Preview 等特定 View。

R31 培训界面的按钮或入口可能不同,应以该 Release 的 Responsive Forms Guide 为准;“Classic 与 Responsive 是同一 Form 下的两份独立 definition”这一边界仍需在目标环境验证。

Responsive Form 不套用 Classic 重建经验

旧文档中的 RebuildViewAction、绝对坐标和 Classic Field 事件不能默认用于 Responsive Form。以目标 Release 编辑器提供的操作为准,并在升级前保留可恢复的 Package。

第 3 步:维护 Classic Form

Classic Form 的常见维护流程:

  1. 在编辑前将 Form 与相关 Method 加入 Package Definition。
  2. 从未使用的 Property 中放置字段,或创建合适控件并设置 Data Source。
  3. 调整标签、坐标、Tab 顺序和可见状态。
  4. 分别测试 New、View、Edit、锁定和只读状态。
  5. 如果使用版本提供的重建动作,只在确认会被覆盖的内容后执行。

重建操作可能覆盖人工布局

不要在已精细排版并绑定事件的 Form 上直接尝试重建。先在隔离环境复制 Form,比较生成结果,再决定是否合并字段。

第 4 步:配置字段状态

字段常见状态包括:

  • Visible:是否显示;
  • Disabled/Read Only:是否允许在当前 UI 编辑;
  • Required 的视觉提示;
  • List、Date、Item 等与 Property 类型匹配的控件。

客户端状态适合改善体验,例如在 acme_is_active=false 时隐藏某个区域。但安全规则必须在服务器端重复实现:用户可以绕过 Form 直接提交 AML。

第 5 步:验证四种上下文

不要只在管理员编辑状态看一眼。至少验证:

上下文要观察的结果
New默认值、必填提示、字段顺序正确
View无锁时不可意外编辑,显示值完整
Edit有权用户可修改,无权用户不能取得编辑能力
状态/身份变化Form 选择和字段状态符合规则

再补充两个尺寸:常用桌面宽度和项目实际支持的最窄宽度。Responsive Form 应检查标签换行、Item 选择器和关系页签,而不只是文本框。

客户端 Method 放在哪里

字段事件、Form 事件、CUI Action 和 Relationship Grid 事件的上下文不同。同一段代码在不同入口中,this、当前 Item 和窗口对象可能完全不同。

新代码开始前先写下:

  1. 触发事件是什么;
  2. 运行在 Classic 还是 Responsive Client;
  3. 当前 Item 从哪个公开上下文取得;
  4. 方法返回值会影响什么;
  5. 异常如何呈现给用户。

详细见 Method 开发与事件上下文

条件显示示例的正确边界

用户旧样例通过 classification 或表头值调用 setVisible / setDisabled。主题可以保留,但应重写成三个层次:

text
服务端 Permission / Event  决定是否真的允许读写
Form 规则或受支持的 API    决定当前交互状态
Classic 私有 DOM 兼容层     只在锁定版本中兜底

不要使用无限 setTimeout 轮询、evalarguments.callee 或吞掉所有异常。需要等待组件时,应有最大次数、明确失败日志,并在升级测试中覆盖。

表单与关系页签

关系页签由 RelationshipType、View/Form 结构和客户端渲染共同决定。按标签文本或固定 iframe GUID 查找页签很脆弱;如果目标 Release 提供 CUI、配置或公开 API,优先使用这些扩展点。

相关旧代码的分类和改写原则见 UI、表单与页签 Cookbook

常见问题

Property 已保存,表单上没有字段

Property 与 Form Field 不会在所有场景自动同步。打开实际绑定的 Form,显式放置字段,并确认你编辑的不是另一个 View。

管理员能打开,普通用户空白或报错

检查 Item、Item Property 的 Data Source、列表和关系对象的 Discover/Get。表单可见性不能补齐数据权限。

禁用字段后,AML 仍可修改

这是预期的安全边界。Disabled 是客户端行为;使用 Permission、Lifecycle 权限或 Server Event 强制业务规则。

Classic 代码在升级后失效

先识别是否依赖 parent[n]、iframe 名、relTabbardocument.thisItemitems_Experimental 等内部结构。将其归入版本兼容层并逐条重做回归,而不是继续增加轮询和吞错。

表单交付检查表
  • [ ] 已标明 Classic/Responsive 与目标 Release
  • [ ] Form 通过正确 View 绑定到 ItemType
  • [ ] New、View、Edit 均验证
  • [ ] 普通用户与管理员均验证
  • [ ] Required/Unique/权限不只依赖客户端
  • [ ] 响应式布局在目标尺寸验证
  • [ ] Client Method 有明确上下文和错误处理
  • [ ] 私有 API 已记录升级风险或被移除
  • [ ] Form、Method、View 依赖已加入 Package

下一步

依据

本站内容仅供学习与参考