【界面设计器】他表字段

阅读之前

你应该:

概述

他表字段是一种可以从关联关系字段中取出对应字段,并平铺在当前模型中的特殊字段。本质上是具有固定【计算公式】的字段。

其主要用于解决GQL在获取关联关系字段时层级过深的问题(非存储的他表字段),也可以用于解决字段冗余的数据同步问题(存储的他表字段)。

这里需要注意的一点是,他表字段的数据同步能力是在客户端进行处理的。无法完全保证数据同步的一致性。

场景描述

为了方便接下来的描述,我们需要先构建一个基本的业务场景,这个场景中包含【商品】、【商品订单】以及【商品订单明细】三个模型。

创建/编辑【商品订单明细】时使用【商品】,【商品】下拉选项中使用【商品编码】 - 【商品名称】格式展示。

在【商品订单明细】展开的表格中展示【商品编码】和【商品名称】,而不是使用【商品】。

其模型定义如下:

商品(Item)
名称 API名称 业务类型 是否多值 长度(单值长度) 关联模型 关联字段
ID id 整数 - - - -
编码 code 文本 128 - - -
名称 name 文本 128 - -
商品订单(ItemOrder)
名称 API名称 业务类型 是否多值 长度(单值长度) 关联模型 关联字段
ID id 整数 128 - -
编码 code 文本 128 - - -
订单明细 details 一对多 - 商品订单明细(ItemOrderDetail) id - orderId
商品订单明细(ItemOrderDetail)
名称 API名称 业务类型 是否多值 长度(单值长度) 关联模型 关联字段
ID id 整数 128 - -
订单 order 多对一 - 商品订单(ItemOrder) orderId - id
订单ID orderId 整数 - - -
商品 item 多对一 - 商品(Item) itemId - id
商品ID itemId 整数 - - -
数量 count 整数 - - -

准备工作

根据模型定义,我们要为【商品】和【商品订单】创建基本的增删改查操作,以此来进行我们接下来的步骤。

(下面仅展示了一些特殊页面,其他页面与基础的增删改查页面没有明显差别)

设计商品订单【表单】视图

将订单明细拖放至页面中,并使用【组件切换】功能将当前的【下拉多选】组件切换至【表格】组件。

image.png

对订单明细所展开的【内嵌表格】进行设计。将【商品】和【数量】两个字段放入表格中。

image.png

设计创建和编辑使用的弹窗视图。(两个按钮都需要设计,这里仅演示创建按钮的设计过程)

image.png

image.png

小贴士:

  • 点击弹窗右上角的X可关闭弹窗设计页面。
  • 左侧【组件库】-【模型】中展示的【当前模型】在选中【订单明细】字段以及它内部的字段或动作时会变为【商品订单明细】关联模型。要想继续设计【商品订单】模型,需要选中任意一个不在【订单明细】字段范围内的组件。在当前视图中可以选中【编码】字段切换至【商品订单】模型。
  • 多模型视图的设计总是需要关注【当前模型】这一信息的。

创建他表字段

目前仅能在界面设计器中通过他表字段组件创建他表字段,在低代码中使用Related定义他表字段。

拖入他表字段,创建【商品编码】字段

image.png

拖入他表字段,创建【商品名称】字段

image.png

隐藏表格中的【商品】字段

image.png

PS:由于他表字段本质上是通过引用的方式取得对象中的值,所以此处不能将该字段直接移除,而是需要隐藏。

在创建/编辑弹窗中添加他表字段并隐藏

image.png

PS:内嵌表格的创建/编辑功能同样会根据元数据进行裁剪,因此要想保证【商品编码】和【商品名称】被正确回填到表格中,这一步骤是必须的。并且为了避免由于使用不同字段导致无法回填的问题,你需要从【组件库】-【模型】中重复使用字段,而不是从【组件】拖入。这并非是他表字段的特性,而是所有内嵌表格都只能通过这种方式进行数据回填。

Oinone社区 作者:oinone原创文章,如若转载,请注明出处:https://doc.oinone.top/designer/60.html

访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验

(0)
oinone的头像oinone
上一篇 2023年6月20日 pm4:07
下一篇 2023年11月2日 pm1:58

相关推荐

  • OioProvider详解(v4.3.0)

    OioProvider OioProvider是平台的初始化入口。 示例入口 main.ts import { VueOioProvider } from '@kunlun/dependencies'; VueOioProvider(); 网络请求/响应配置 http 平台统一使用apollo作为统一的http请求发起服务,并使用GraphQL协议作为前后端协议。 参考文档: apollo-client graphql 配置方式 VueOioProvider({ http?: OioHttpConfig }); OioHttpConfig /** * OioHttp配置 */ export interface OioHttpConfig { /** * base url */ url: string; /** * 拦截器配置 */ interceptor?: Partial<InterceptorOptions>; /** * 中间件配置(优先于拦截器) */ middleware?: NetworkMiddlewareHandler | NetworkMiddlewareHandler[]; } 内置拦截器可选项 InterceptorOptions /** * 拦截器可选项 */ export interface InterceptorOptions { /** * 网络错误拦截器 */ networkError: NetworkInterceptor; /** * 请求成功拦截器 (success) */ requestSuccess: NetworkInterceptor; /** * 重定向拦截器 (success) */ actionRedirect: NetworkInterceptor; /** * 登录重定向拦截器 (error) */ loginRedirect: NetworkInterceptor; /** * 请求错误拦截器 (error) */ requestError: NetworkInterceptor; /** * MessageHub拦截器 (success/error) */ messageHub: NetworkInterceptor; /** * 前置拦截器 */ beforeInterceptors: NetworkInterceptor | NetworkInterceptor[]; /** * 后置拦截器 */ afterInterceptors: NetworkInterceptor | NetworkInterceptor[]; } 内置拦截器执行顺序: beforeInterceptors:前置拦截器 networkError:网络错误 actionRedirect:重定向 requestSuccess 请求成功 loginRedirect:登录重定向 requestError:请求错误 messageHub:MessageHub afterInterceptors:后置拦截器 NetworkInterceptor /** * <h3>网络请求拦截器</h3> * <ul> * <li>拦截器将按照注册顺序依次执行</li> * <li>当任何一个拦截器返回false时,将中断拦截器执行</li> * <li>内置拦截器总是优先于自定义拦截器执行</li> * </ul> * */ export interface NetworkInterceptor { /** * 成功拦截 * @param response 响应结果 */ success?(response: IResponseResult): ReturnPromise<boolean>; /** * 错误拦截 * @param response 响应结果 */ error?(response: IResponseErrorResult): ReturnPromise<boolean>; } 自定义路由配置 router 配置方式 VueOioProvider({ router?: RouterPath[]…

    2023年11月1日
    1.8K00
  • 数据可视化的导入导出

    目录 依赖包安装GraphQL的工具登录gql导出生成json文件子业务工程中导入示例代码 简介 通过调用导出接口,将设计器的设计数据与元数据打包导出到文件中。提供了download/export两类接口。 依赖包 <dependency> <groupId>pro.shushi.pamirs.metadata.manager</groupId> <artifactId>pamirs-metadata-manager</artifactId> </dependency> 安装GraphQL的工具 下载官网地址:https://github.com/Kong/insomnia/releases 登录gql 示例调用代码 mutation { pamirsUserTransientMutation { login(user: { login: "admin", password: "admin" }) { needRedirect broken errorMsg errorCode errorField } } } 导出生成json文件 执行GraphQL,直接返回导出数据。适用于通过浏览器直接下载文件。 全部导出 请求示例: mutation { dataDesignerExportReqMutation { export(data: { fileName: "datavi_data" }) { jsonUrl } } } 指定图表导出 请求示例: mutation { dataDesignerExportReqMutation { export(data: { chartCode: "CT00000000002000", fileName: "datavi_data" }) { jsonUrl } } } 对应chartCode为图表的编码code,可通过查询数据库来获得 指定报表导出 请求示例: mutation { dataDesignerExportReqMutation { export(data: { reportCode: "RP00001000", fileName: "datavi_data" }) { jsonUrl } } } 对应reportCode为报表的编码code,可通过查询数据库来获得 指定业务大屏导出 请求示例: mutation { dataDesignerExportReqMutation { export(data: { screenCode: "DS00001000", fileName: "datavi_data" }) { jsonUrl } } } 对应screenCode为数据大屏的编码code,可通过查询数据库来获得 业务工程中导入示例代码 导入元数据示例代码 @Slf4j @Order(Integer.MAX_VALUE-1) @Component public class DemoModuleAppInstall implements MetaDataEditor, LifecycleCompletedAllInit { //流程设计器导出的页面元数据json private static final String INSTALL_DATAVI_META_PATH = "install/datavi_data.json"; @Override public void edit(AppLifecycleCommand command, Map<String, Meta> metaMap) { if(StringUtils.isBlank(INSTALL_DATAVI_META_PATH)) return; log.info("开始安装-元数据"); try { InitializationUtil util = InitializationUtil.get(metaMap, DemoModule.MODULE_MODULE, DemoModule.MODULE_NAME); if (null != util) { // 设计器的元数据 if(StringUtils.isNotBlank(INSTALL_DATAVI_META_PATH)) { log.info("开始安装图表元数据"); DesignerInstallHelper.mateInitialization(util, INSTALL_DATAVI_META_PATH); } } } catch (Exception e) { log.error("图表设计器元数据导入异常", e); } } @Override public void process(AppLifecycleCommand command, Map<String, ModuleDefinition> runModuleMap) {…

    2024年5月16日
    2.0K00
  • 如何把平台功能菜单加到项目中?

    概述 在使用Oinone低代码平台进行项目开发的过程中,会存在把平台默认提供的菜单加到自己的项目中。这篇文章介绍实现方式,以角色管理为例。 1. 低代码情况 即项目是通过后端代码初始化菜单的方式。 通常在 XXXMenu.java类通过@UxMenu注解的方式,代码片段如下: 此种情况与添加项目本地的菜单无区别,具体代码: @UxMenu(value = "账号管理", icon = "icon-yonghuguanli") class AccountManage { @UxMenu("用户管理") @UxRoute(value = CustomerCompanyUserProxy.MODEL_MODEL, title = "用户管理") class CompanyUserManage { } @UxMenu("角色管理") @UxRoute(value = AuthRole.MODEL_MODEL, module = AdminModule.MODULE_MODULE, title = "角色管理") class RoleManage { } @UxMenu("操作日志") @UxRoute(value = OperationLog.MODEL_MODEL, module = AdminModule.MODULE_MODULE/***菜单所挂载的模块**/) class OperateLog { } } 2. 无代码情况 在界面设计器中,新建菜单–>选择绑定已有页面,进行发布即可。

    2024年4月19日
    1.7K00
  • 界面设计器创建批量更新的动作

    界面设计器如果创建批量更新的动作 一、拖拽批量动作到表格区域 拖拽批量动作至表格区域,创建批量更新动作设置动作信息,设置完成之后点击保存 二、设置批量动作弹窗视图 点击设计弹窗,出现弹窗设计器界面将需要批量更新的字段拖入表单区,将待提交的数据需要展示字段拖入表格区域,比如更新名称,展示待提交数据的ID、名称、创建时间(注意:创建时间需要在表格中也展示)拖拽客户端动作进入动作区域,并设置动作信息,客户端行为选择批量更新动作设置成功,点击保存 三、发布设计好的批量动作,在运行页面看看效果 选择批量更新的数据之后点击批量更新将名称修改为‘批量修改名称’查看最后实现效果

    2024年4月22日
    2.6K00
  • 弹窗或抽屉表单视图rootRecord获取不到对应的数据

    在平台默认的实现中,rootRecord 代表的是根视图的数据。比如,在表格页面点击按钮打开了弹窗,弹窗里面包含一个表单视图,但是该视图获取 rootRecord 却是最外层的视图数据。 如果期望 rootRecord 数据是弹窗的视图数据,需要手动修改表单的 rootRecord。下面的代码演示了如何重写 rootData 以确保其数据是弹窗的数据: @SPI.ClassFactory( BaseElementWidget.Token({ viewType: ViewType.Form, widget: 'MyCustomFormWidgetFormWidget' }) ) export class MyCustomFormWidgetFormWidget extends FormWidget { @Widget.Reactive() @Widget.Provide() public get rootData(): any[] | undefined { return this.activeRecords; } } 上述代码重写了 rootData,这样就可以确保 rootData 的数据是弹窗的数据。 接下来就是注册: registerLayout( ` <view type="FORM"> <element widget="actionBar" slot="actionBar" slotSupport="action"> <xslot name="actions" slotSupport="action" /> </element> <element widget="MyCustomFormWidgetFormWidget" slot="form"> <xslot name="fields" slotSupport="pack,field" /> </element> </view> `, { viewType: ViewType.Form, model: '弹窗模型', viewName: '弹窗视图名称' } )

    2023年11月13日
    1.5K00

Leave a Reply

登录后才能评论