【界面设计器】树下拉/级联

阅读之前

你应该:

名词解释

  • 字段组件:为字段提供交互能力的组件,一个字段对应一个组件。
  • 关联关系字段:在模型中与其他模型建立关联关系的字段。
  • 可选项:选择组件使用的具体选项,可以是静态的,也可以是动态的。
  • 选中:用户在使用选择组件时,针对某一选项标记或提取这一选项。

概述

本章内容主要是对【界面设计器】左树右表内容中提及的字段相关内容的补充,并非完整教程,有不清楚的地方可以交替阅读进行理解。

场景

沿用【界面设计器】左树右表中的两个场景。

我们可以做出这些优化:

将【商品类目】的【上级类目】组件改为【级联】组件。其第1级为【商品类目】,使用自关联依次展开。

将【部门】的【上级部门】组件改为【树下拉】组件。其第1级为【公司】,第2级为【部门】,【部门】使用自关联依次展开。

PS:本章不提供任何步骤介绍,请根据场景内容自行探索。

扩展知识

具备选择行为的组件

常用的选择组件可以进行一些基本的划分。

从可选数量来看
  • 单选:只能选一个值。
  • 多选:可以选择多个值。
从业务类型来看
  • 枚举(Enum):通过数据字典提供可选项。
  • 布尔(Boolean):可以看作一个特殊的枚举,其可选范围只有是和否。
  • 一对一(O2O)和多对一(M2O):对一(X2O)类型仅支持单选,通过关联模型的数据源提供可选项。
  • 一对多(O2M)以及多对多(M2M):对多(X2M)类型仅支持多选,通过关联模型的数据源提供可选项。
从交互形态来看
  • 单选框(Radio)
  • 多选框(Checkbox)
  • 下拉选择(Select)
  • 树下拉(TreeSelect)
  • 级联(Cascader)

其中,树下拉(TreeSelect)和级联(Cascader)组件要求数据源可以构成树结构,因此通常使用这两个字段组件的都是关联关系字段。

下拉选择(Select)

在介绍树下拉/级联之前,我们有必要先了解一下在关联关系字段中使用下拉选择(Select)这一字段组件的表现情况。

根据关联关系字段对应的关联模型,我们可以获得其组件所需的可选项,在用户进行选中后,该组件将获得一个选项值,并且在表单提交、计算公式等被使用。

通常情况下,我们通过queryPage接口获取分页后的可选项列表,再通过点击/滚动方式获得其他页的可选项供用户选择。

树下拉(TreeSelect)/级联(Cascader)

与上述介绍的下拉选择(Select)不同点在于,其可选项是通过【联动关系】配置进行获取的,它并不要求直接获取到真正可以被选择的可选项,而是通过树结构依次展开的。用户可选择的可选项一定是与关联关系字段对应的关联模型相同的树节点。对于无法选择的节点,其主要作用在于将数据进行划分,以便于用户进行选择。

由于树节点具备特殊性,无法直接使用平台的任何一个模型。因此树结构被定义在UiTreeNode模型中,该模型是描述树结构的基本模型,其提供了多个接口为树结构的查询提供了基本能力。

通常情况下,在创建页面,我们通过UiTreeNode模型的fetchChildren接口依次获取其子节点。在编辑页面,我们通过fetchAll、reverselyQuery、reverselyQueryWithSize这三个接口获取回填的数据,根据不同情况进行调用。虽然使用来不同的接口,但最终都会使用当前模型的queryPage接口获取数据。

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

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

Like (0)
oinone's avataroinone
Previous 2023年6月20日 pm4:07
Next 2023年11月2日 pm1:58

相关推荐

  • 【工作流】流程扩展自定义函数示例代码汇总

    目录 1. 流程节点审批人函数2. 审批开始前执行函数3. 填写执行前执行函数4. 待办操作提交后执行函数5. 审批操作数据函数6. 自定义通知人函数 1. 流程节点审批人函数 包含转交、抄送、加签、填写、通知人自定义函数当平台默认提供的审批人选择无法满足个性化的业务需求时,我们可以通过自定义函数处理审批人的生成逻辑 1.1 编写自定义审批人函数 @Function(openLevel = {FunctionOpenEnum.API}) @Function.Advanced(type = FunctionTypeEnum.QUERY, displayName = "报销单-证明人-审批", category = CUSTOM_DESIGNER) public List<NodePerson> bizZmrApprovePerson(List<NodePerson> nodePersonList, NodeModel nodeModel, WorkflowContext workflowContext) { List<NodePerson> newNodePersonList = new ArrayList<>(); String nodeModelId = nodeModel.getId(); Object nodeData = workflowContext.get(nodeModelId); BuissModel inputBuissModel = JsonUtils.parseObject(JsonUtils.toJSONString(nodeData), BUISSMODEL_TR); BuissModel buissModel = new BuissModel().setId(inputBuissModel.getId()).queryById(); buissModel.fieldQuery(BuissModel::getZmEmployee); BxEmployee zmEmployee = buissModel.getZmEmployee(); if (zmEmployee == null) { log.error("报销单ID:{},名称:{}, 获取证明人为空", buissModel.getId(), buissModel.getName()); return newNodePersonList; } NodePersonUser personUser = new NodePersonUser(); List<NodePersonUser> nodePersonUsers = new ArrayList<>(); NodePerson person = new NodePerson(); person.setId(zmEmployee.getBindingUserId() + ""); person.setType(NodePersonTypeEnum.USER); personUser.setUserId(zmEmployee.getBindingUserId()); nodePersonUsers.add(personUser); person.setNodePersonUsers(nodePersonUsers); newNodePersonList.add(person); return newNodePersonList; } 1.2 流程设计器的审批节点设置自定义函数 2.审批开始前执行函数 使用场景:在流程执行到审批或填写节点任务初始化后,任务尚未开始,需要在初始化任务做一些自定义逻辑处理时,使用该扩展执行时间:执行节点是在审批或填写待办任务初始化之后,审批或填写结果执行之前,执行该扩展 /** * 审批节点初始化完成,执行前置函数 * @param approvalNode * @param context * @param taskInstance */ @Function(name = "approvalCustomStartFun",openLevel = FunctionOpenEnum.API) @Function.Advanced(type= FunctionTypeEnum.QUERY,displayName = "审批执行前置处理",category = FunctionCategoryEnum.CUSTOM_DESIGNER ) public void approvalCustomStartFun(ApprovalNode approvalNode, WorkflowContext context, WorkflowTaskInstance taskInstance) { // TODO: 2024/2/23 可以根据结果自己处理业务逻辑 } 3.填写执行前执行函数 /** * 填写执行前置处理 */ @Function(name = "writeCustomStartFun", openLevel = FunctionOpenEnum.API) @Function.Advanced(type = FunctionTypeEnum.QUERY, displayName = "填写执行前置处理", category = FunctionCategoryEnum.CUSTOM_DESIGNER) public void writeCustomStartFun(WorkflowTaskInstance taskInstance, WriteNode writeNode, WorkflowContext context) { System.out.println("填写执行前置处理"); } 4. 待办操作提交后执行函数 使用场景:在审批或填写的待办任务在操作任务时,需要额外执行一些逻辑,比如当前人提交操作以后需要更新更当前人操作相关的数据库记录,执行时间:执行节点是在保存待办任务之后,异步执行审批或填写结果之前,执行该扩展 /** * 转交操作后置函数,再流程设计器中审批和填写节点中…

    2023年12月4日
    2.5K00
  • 数据可视化-项目中如何引用图表、报表、大屏

    依赖包 在业务工程的pom中增加数据可视化运行的依赖包 参考文档 如何添加数据可视化运行时依赖 数据可视化设计图表、报表和数据大屏 在数据可视化中设计好业务合适的图表,并且发布以后,在界面设计器中可以嵌入该图表同样处理的还有报表 在界面设计器中在页面中透出图表、报表和数据大屏 设置图表,选择已经对应的图表 可在表单以及详情的页面中嵌入对应的图表、报表和数据大屏 更新图表、报表和数据大屏 修改图表以后,需要更新发布,对应业务页面上才会更新最新的图表

    2024年5月18日
    2.0K00
  • 数据可视化的导入导出

    目录 依赖包安装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.5K00
  • 数据可视化-如何自定义查询数据方法

    场景 根据测试商品,汇总数据通过测试统计商品透出到数据可视化图表数据; 统计商品类目的最大库存以及平均售价信息 测试商品模型 @Model.model(DemoItem.MODEL_MODEL) @Model(displayName = "测试商品", labelFields = "name") @Model.Code(sequence = "SEQ", prefix = "IT", size = 8) public class DemoItem extends CodeModel { private static final long serialVersionUID = -5104390780952631397L; public static final String MODEL_MODEL = "demo.DemoItem"; @Field.String @Field(displayName = "商品名称") private String name; @Field.Html @Field(displayName = "商品描述") private String description; @Field.Money(D=2) @Field(displayName = "商品价格") private BigDecimal itemPrice; @Field.Integer @Field(displayName = "商品库存") private Long inventoryQuantity; …. 测试商品统计 @Model.model(DemoItemStatistics.MODEL_MODEL) @Model(displayName = "测试商品统计", labelFields = "name") public class DemoItemStatistics extends IdModel { private static final long serialVersionUID = 5626273740800455515L; public static final String MODEL_MODEL = "demo.DemoItemStatistics"; @Field.String @Field(displayName = "类目名称") private String categoryName; @Field.Integer @Field(displayName = "商品库存") private Long inventoryQuantity; @Field.Money @Field(displayName = "商品价格") private BigDecimal itemPrice; } 自定义商品类目统计数据 【注意】 图表设计器能获取到的接口需指定:category = FunctionCategoryEnum.QUERY_PAGE,且出参和入参类型要与本示例一致 @Function.Advanced(type = FunctionTypeEnum.QUERY, displayName = "商品统计列表", category = FunctionCategoryEnum.QUERY_PAGE) @Function.fun(FunctionConstants.queryPage) @Function(openLevel = {FunctionOpenEnum.LOCAL, FunctionOpenEnum.REMOTE, FunctionOpenEnum.API}) public Pagination<DemoItemStatistics> queryPage(Pagination<DemoItemStatistics> page, IWrapper<DemoItemStatistics> queryWrapper) { List<DemoItemStatistics> list = new ArrayList<>(); List<DemoItem> items = demoItemService.queryListByWrapper(Pops.<DemoItem>lambdaQuery() .from(DemoItem.MODEL_MODEL) .eq(DemoItem::getStatus, ItemStatusEnum.ACTIVE)); if(CollectionUtils.isEmpty(items)) return page; Map<Long, List<DemoItem>> itemMap = items.stream().collect(Collectors.groupingBy(DemoItem::getCategoryId)); for (Map.Entry<Long, List<DemoItem>> longListEntry : itemMap.entrySet()) { long categoryId = longListEntry.getKey(); List<DemoItem> demoItems =…

    2024年5月18日
    1.8K00
  • 创建与编辑一体化

    在业务操作中,用户通常期望能够在创建页面后立即进行编辑,以减少频繁切换页面的步骤。我们可以充分利用Oinone平台提供的创建与编辑一体化功能,使操作更加高效便捷。 通过拖拽实现表单页面设计 在界面设计器中,我们首先需要设计出对应的页面。完成页面设计后,将需要的动作拖入设计好的页面。这个动作的关键在于支持一个功能,即根据前端传入的数据是否包含id来判断是创建操作还是编辑操作。 动作的属性配置如下: 前端自定义动作 一旦页面配置完成,前端需要对这个动作进行自定义。以下是一个示例的代码: @SPI.ClassFactory( ActionWidget.Token({ actionType: [ActionType.Server], model: '模型', name: '动作的名称' }) ) export class CreateOrUpdateServerActionWidget extends ServerActionWidget { @Widget.Reactive() protected get updateData(): boolean { return true; } } 通过以上步骤,我们实现了一个更智能的操作流程,使用户能够在创建页面的同时进行即时的编辑,从而提高了整体操作效率。这种创建与编辑一体化的功能不仅使操作更加顺畅,同时也为用户提供了更灵活的工作流程。

    2023年11月21日
    2.8K00

Leave a Reply

Please Login to Comment