3.5.2.1 整体介绍

虽然我们有小眼睛可以让用户自定义展示字段和排序喜好,以及通过权限控制行、列展示,但在我们日常业务开发中还是会对页面进行调整,以满足业务方的对交互友好和便捷性的要求。本节会在如何自定义之前我们先介绍页面结构与逻辑,再带小伙伴一起完成自定义view的Template和Layout,以及整个母版的Template和Layout

页面的构成讲解

页面交互拓扑图

页面交互拓扑图

3.5.2.1 整体介绍

图3-5-2-1 页面交互拓扑图

注:页面逻辑交互拓扑图说明

  1. 模块作为主切换入口

  2. 模块决定菜单列表

  3. 菜单切换触发点击action

  4. 前端根据Mask、View进行渲染,

a. Mask是母版是确定了主题、非主内容分发区域所使用组件和主内容分发区域联动方式的页面模板。全局、应用、视图动作、视图都可以通过mask属性指定母版

bMask和View都是有layout定义和template定义合并而成,系统会提供默认母版,以及为每种视图提供默认layout

c. layout与template通过插槽进行匹配

  1. Action根据不同类型做出不同访问后端服务、url跳转、页面路由、发起客户端动作等

  2. Aciton路由可以指定Mask、视图组件的layout、template

a. 当layout没有指定的时候则用系统默认的

b. 当template没有指定的时候,且视图组件相同类型有多条记录时,根据优先级选取

  1. Mask和视图组件的layout优先级(视图组件>视图动作 > 应用 > 全局)

默认母版以及各类视图组件

母版布局

默认母版基础布局base-layout
<mask layout="default">
    <header slot="header"/>
    <container slot="main" name="main">
        <sidebar slot="sidebar"/>
        <container slot="content"/>
    </container>
    <footer slot="footer"/>
</mask>

图3-5-2-2 默认母版基础布局base-layout

母版template
<mask layout="default">
    <mask name="defaultMask">
    <template slot="header">
        <container name="appBar">
            <element widget="logo"/>
            <element widget="appFinder"/>
        </container>
        <container name="operationBar">
            <element widget="notification"/>
            <element widget="dividerVertical"/>
            <element widget="languages"/>
        </container>
        <element widget="userProfile"/>
    </template>
    <template slot="sidebar">
        <element widget="navMenu"/>
    </template>
    <template slot="content">
      <element widget="breadcrumb"/>
      <element widget="mainView"/>
    </template>
</mask>

图3-5-2-3 母版template

注:

  • 上例中因为名称为main的插槽不需要设置更多的属性,所以在template中缺省了main插槽的template标签。
最终可执行视图
<mask name="defaultMask">
    <header>
        <container name="appBar">
            <element widget="logo"/>
            <element widget="appFinder"/>
        </container>
        <container name="operationBar">
            <element widget="notification"/>
            <element widget="dividerVertical"/>
            <element widget="languages"/>
        </container>
        <element widget="userProfile"/>
    </header>
    <container name="main">
        <sidebar name="sidebar">
            <element widget="navMenu"/>
        </sidebar>
        <container name="content">
            <element widget="breadcrumb"/>
            <element widget="mainView"/>
        </container>
    </container>
    <footer/>
</mask>

图3-5-2-4 最终可执行视图

表格视图布局

默认表格视图基础布局base-layout
<view type="table">
    <view type="search">
        <element widget="search" slot="search">
            <xslot name="fields" slotSupport="field" />
        </element>
    </view>
    <pack widget="fieldset">
        <element widget="actionBar" slot="actions" slotSupport="action" />
        <element widget="table" slot="table">
            <xslot name="fields" slotSupport="field" />
            <element widget="actionsColumn" slot="actionsColumn">
                <xslot name="rowActions" slotSupport="action" />
            </element>
        </element>
    </pack>
</view>

图3-5-2-5 默认表格视图基础布局base-layout

注:table标签的子标签为column组件,如果field填充到元数据插槽fields没有column组件将自动包裹column组件。

表格视图template
<view type="table" model="xxx" name="tableViewExample">
    <template slot="search">
        <field data="name"/>
    </template>
    <template slot="actions">
        <action name="create"/>
    </template>
    <template slot="fields">
        <field data="id"/>
        <field data="name"/>
        <field data="code"/>
    </template>
    <template slot="rowActions">
        <action name="delete"/>
        <action name="update"/>
    </template>
</view>

图3-5-2-6 表格视图template

最终可执行视图
<view type="table" model="xxx" name="tableViewExample">
    <view type="search">
        <element widget="search">
            <field data="name"/>
        </element>
    </view>
    <action-bar>
        <action name="create"/>
    </action-bar>
    <table>
        <column>
            <field data="id"/>
        </column>
        <column>
            <field data="name"/>
        </column>
        <column>
            <field data="code"/>
        </column>
        <column>
            <action name="delete"/>
            <action name="update"/>
        </column>
    </table>
</view>

图3-5-2-7 最终可执行视图

表单视图布局

默认表单视图基础布局base-layout
<view type="form">
    <element widget="actionBar" slot="actions" slotSupport="action"/>
    <element widget="form" slot="form">
        <xslot name="fields" slotSupport="pack,field"/>
    </element>
</view>

图3-5-2-8 默认表单视图基础布局base-layout

表单视图template
<view type="form" model="xxx" name="viewExample">
    <template slot="actions">
        <action name="submit"/>
    </template>
    <template slot="fields">
        <pack widget="group">
            <field data="id"/>
            <field data="name" widget="string"/>
            <field data="code"/>
        </pack>
        <pack widget="tabs">
            <pack widget="tab" title="商品列表">
                <field data="items" />
            </pack>
            <pack widget="tab" title="子订单列表">
                <field data="orders" />
            </pack>
        </pack>
    </template>
</view>

图3-5-2-9 表单视图template

注:tabs标签的子标签为tab,如果dsl填充到layout没有tab标签将自动包裹tab标签。

最终可执行视图
<view type="form" model="xxx" name="viewExample">
    <action-bar>
        <action name="submit"/>
    </action-bar>
    <form>
        <group>
            <field data="id"/>
            <field data="name" widget="string"/>
            <field data="code"/>
        </group>
        <tabs>
            <tab title="商品列表">
                <field data="items" />
            </tab>
            <tab title="子订单列表">
                <field data="orders" />
            </tab>
        </tabs>
    </form>
</view>

图3-5-2-10 表单视图template

详情视图布局

默认详情视图基础布局base-layout
<view type="detail">
    <element widget="actionBar" slot="actions" slotSupport="action"/>
    <element widget="detail" slot="detail">
        <xslot name="fields" slotSupport="pack,field"/>
    </element>
</view>

图3-5-2-11 默认详情视图基础布局base-layout

详情视图template
<view name="viewExample">
    <template slot="actions">
        <action name="back"/>
    </template>
    <template slot="fields">
        <pack widget="group">
            <field data="id"/>
            <field data="name" widget="string"/>
            <field data="code"/>
        </pack>
        <pack widget="tabs">
            <pack widget="tab" title="商品列表">
                <field data="items" />
            </pack>
            <pack widget="tab" title="子订单列表">
                <field data="orders" />
            </pack>
        </pack>
    </template>
</view>

图3-5-2-12 详情视图template

最终可执行视图
<view type="detail" model="xxx" name="viewExample">
    <action-bar>
        <action name="back"/>
    </action-bar>
    <detail>
        <group>
            <field data="id"/>
            <field data="name" widget="string"/>
            <field data="code"/>
        </group>
        <tabs>
            <tab title="商品列表">
                <field data="items" />
            </tab>
            <tab title="子订单列表">
                <field data="orders" />
            </tab>
        </tabs>
    </detail>
</view>

图3-5-2-13 最终可执行视图

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

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

(0)
史, 昂的头像史, 昂数式管理员
上一篇 2024年5月23日 am9:26
下一篇 2024年5月23日

相关推荐

  • 3.4.3.1 面向对象-继承与多态

    本节为小伙伴们介绍,Function的面向对象的特性:继承与多态; 一、继承 我们在3.4.1【构建第一个Function】一文中伴随模型新增函数和独立类新增函数绑定到模型部分都是在父模型PetShop新增了sayHello的Function,同样其子模型都具备sayHello的Function。因为我们是通过Function的namespace来做依据的,子模型在继承父模型的sayHello函数后会以子模型的编码为namespace,名称则同样为sayHello。 二、多态(举例) oinone的多态,我们只提供覆盖功能,不提供重载,因为oinone相同name和fun的情况下不会去识别参数个数和类型。 Step1 为PetShop新增hello函数 package pro.shushi.pamirs.demo.api.model; …… //import @Model.model(PetShop.MODEL_MODEL) @Model(displayName = "宠物店铺",summary="宠物店铺",labelFields ={"shopName"} ) @Model.Code(sequence = "DATE_ORDERLY_SEQ",prefix = "P",size=6,step=1,initial = 10000,format = "yyyyMMdd") public class PetShop extends AbstractDemoIdModel { public static final String MODEL_MODEL="demo.PetShop"; …… //省略其他代码 @Function(openLevel = FunctionOpenEnum.API) @Function.Advanced(type= FunctionTypeEnum.QUERY) public PetShop sayHello(PetShop shop){ PamirsSession.getMessageHub().info("Hello:"+shop.getShopName()); return shop; } @Function(name = "sayHello2",openLevel = FunctionOpenEnum.API) @Function.Advanced(type= FunctionTypeEnum.QUERY) @Function.fun("sayHello2") public PetShop sayHello(PetShop shop, String s) { PamirsSession.getMessageHub().info("Hello:"+shop.getShopName()+",s:"+s); return shop; } @Function(openLevel = FunctionOpenEnum.API) @Function.Advanced(type= FunctionTypeEnum.QUERY) public PetShop hello(PetShop shop){ PamirsSession.getMessageHub().info("Hello:"+shop.getShopName()); return shop; } } 图3-4-3-1 为PetShop新增hello函数 Step2 为PetShopProxyB新增对应的三个函数 其中PetShopProxyB新增的hello函数,在java中是重载了hello,在代码中new PetShopProxyB()是可以调用父类的sayHello单参方法,也可以调用本类的双参方法。但在oinone的体系中对于PetShopProxyB只有一个可识别的Function就是双参的sayHello package pro.shushi.pamirs.demo.api.proxy; import pro.shushi.pamirs.demo.api.model.PetCatItem; import pro.shushi.pamirs.demo.api.model.PetShop; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Function; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.api.session.PamirsSession; import pro.shushi.pamirs.meta.enmu.FunctionOpenEnum; import pro.shushi.pamirs.meta.enmu.FunctionTypeEnum; import pro.shushi.pamirs.meta.enmu.ModelTypeEnum; import java.util.List; @Model.model(PetShopProxyB.MODEL_MODEL) @Model.Advanced(type = ModelTypeEnum.PROXY,inherited ={PetShopProxy.MODEL_MODEL,PetShopProxyA.MODEL_MODEL} ) @Model(displayName = "宠物店铺代理模型B",summary="宠物店铺代理模型B") public class PetShopProxyB extends PetShop { public static final String MODEL_MODEL="demo.PetShopProxyB"; @Field.one2many @Field(displayName = "萌猫商品列表") @Field.Relation(relationFields = {"id"},referenceFields = {"shopId"}) private List<PetCatItem> catItems; @Function(openLevel = FunctionOpenEnum.API) @Function.Advanced(type= FunctionTypeEnum.QUERY) public PetShop sayHello(PetShop shop){ PamirsSession.getMessageHub().info("PetShopProxyB Hello:"+shop.getShopName()); return shop; } @Function(name = "sayHello2",openLevel = FunctionOpenEnum.API) @Function.Advanced(type= FunctionTypeEnum.QUERY) @Function.fun("sayHello2") public PetShop sayHello(PetShop shop,String hello){ PamirsSession.getMessageHub().info("PetShopProxyB say:"+hello+","+shop.getShopName()); return shop; } @Function(openLevel = FunctionOpenEnum.API)…

    2024年5月23日
    1.1K00
  • 陈浩

    自2017年中国推进数字建设以来,数字经济规模持续增长,“十四五”规划和2035远景目标纲要中明确强调企业和政府需大力推动数字化转型,中国正在迈进一个崭新的数字经济时代。 在这个过程中,软件已经从工具变成信息化的基础设施,如何有效应对该变化所带来的一系列新的核心技术挑战,是整个软件行业发展遇到的另一难题。我认为,开源创新是解决这些难题的有效手段之一,也是未来软件发展的重要方向。如果说,数字化转型是时代趋势,那么开源创新也已成为时代主流。十四五规划纲要首提开源,2021年11月工信部印发《十四五软件和信息技术服务业发展规划》中提到开源重塑软件发展新生态,并将开源重塑软件发展新生态作为十四五期间我国软件产业的四大发展形势之一进行重点阐述。支持国产化开源创新体系发展,建设自己的开源社区和开源平台,其所具有的大众协同、开放共享、持续创新等特点,可有效推动各行业自主可控的数字化转型。 Oinone所倡导的开源理念和生态共建,与国家开源战略不谋而合:将开源作为一种合作手段,通过完善社区注重开源治理,吸引更多的企业和个体参与其中。湖南大学作为首批国家示范性软件学院的双一流建设高校,一直致力于推进和引导国产化开源软件体系的建设,并为此开展多种形式的产学研研究和实践。基于Oinone微服务分布式的设计理念和面向生态的开源特性,湖南大学结合自身在大数据分布式存储、多元异构数据汇聚融合和大数据智能分析等方面的研究成果,与Oinone展开了深度的技术创新合作,并在多个大中型企业数字化应用和数字政府应用中取得了良好的效果。 随着Oinone的开源,相信能激发更多的开发者参与到国产软件建设中,通过开源模式实现更广泛参与方的共享、共创、共生、共赢,构建价值驱动的数字创新生态平台,为我国数字经济发展贡献科技力量。 湖南大学教授:陈浩

    Oinone 7天入门到精通 2024年5月23日
    1.3K00
  • 3.5.5 设计器的结合(改)

    在页面开发的时候,直接通过前端组件和视图xml进行开发虽然开放性是很大的、但我们经常会忘记视图的配置属性,同时用xml配置的页面因为缺少设计数据,导致无法直接在设计器中复制,自定义页面得从头设计。今天就带大家一起来学习如何结合无代码设计器来完成页面开发,并把设计后的页面元数据装载为标准产品的一部分。 1 安装Docker 如果没有Docker的话,请自行到官网下载:https://www.docker.com/get-started/ 2 下载Docker 镜像,并导入镜像 Step2.1 镜像下载 v.4.6.28.3-allinone-full 版本说明 前后端以及中间件一体 镜像地址 docker pull harbor.oinone.top/oinone/designer:4.6.28.3-allinone-full 下载结构包 oinone-op-ds-all-full.zip(17 KB) v.4.6.28.3-allinone-mini 版本说明 前后端一体支持外部中间件 镜像地址 docker pull harbor.oinone.top/oinone/designer:4.6.28.3-allinone-mini 下载结构包 oinone-op-ds-all-mini.zip(14 KB) v.4.7.9-allinone-full 版本说明 前后端以及中间件一体 镜像地址 docker pull harbor.oinone.top/oinone/designer:4.7.9-allinone-full 下载结构包 oinone-op-ds-all-full.zip(17 KB) v.4.7.9-allinone-mini 版本说明 前后端一体支持外部中间件 镜像地址 docker pull harbor.oinone.top/oinone/designer:4.7.9-allinone-mini 下载结构包 oinone-op-ds-all-mini.zip(14 KB) Step2.1.2 镜像下载用户与密码 需要商业版镜像需要加入Oinone商业版本伙伴专属群,向Oinone技术支持获取用户名与密码,镜像会定时更新并通知大家。 #注意:docker镜像拉取的账号密码请联系数式技术 docker login –username=用户名 harbor.oinone.top docker pull docker pull harbor.oinone.top/oinone/designer:4.6.28.3-allinone-full Step2.1.3 镜像和版本选择 目前有2个版本可供选择,包含中间件以及不包含中间件2个版本,下载结构包以后注意修改startup.sh和startup.cmd中对应镜像地址的版本号。 Step2.1.4 本地结构说明 下载结构包并解压 config是放application.yml的目录,可以在application.yml配置需要启动的自有模块同时修改对应其他中间件配置项 lib是放自有模块的jar包以及其对应的依赖包比如:pamirs-demo-api-1.0.0-SNAPSHOT.jar和pamirs-demo-core-1.0.0-SNAPSHOT.jar nginx:前端运行的nginx站点配置文件 mq:消息配置,再使用低无一体时需要指定mq的broker的IP run:容器运行中间件的脚本,可以对个别中间件是否启动进行设置,(注释掉运行脚本,容器启动时就不会启动该中间件) logs是运行时系统日志目录 Step2.2 修改startup.sh中的路径 Step2.2.1 linux环境修改参数 在文件中找到如下 configDir=/opt/docker/oinone-op-ds-all-full version=4.6.28.3 IP=192.168.0.121 修改configDir的路径(下载oinone-op-ds-xx.zip解压后的路径) 修改对应的镜像版本号 修改对应的IP为docker宿主机IP #!/bin/bash configDir=/opt/docker/oinone-op-ds-all-full version=4.6.28.3 IP=192.168.0.121 docker run -d –name designer-allinone \ -e DUBBO_IP_TO_REGISTRY=$IP \ -e DUBBO_PORT_TO_REGISTRY=20880 \ -p 8099:8091 \ -p 3307:3306 \ -p 2182:2181 \ -p 6378:6379 \ -p 19876:9876 \ -p 10991:10991 \ -p 15555:15555 \ -p 20880:20880 \ -p 88:80 \ -v $configDir/config/:/opt/pamirs/ext \ -v $configDir/nginx:/opt/pamirs/nginx/vhost \ -v $configDir/logs:/opt/pamirs/logs \ -v $configDir/mq/broker.conf:/opt/mq/conf/broker.conf \ -v $configDir/run/run.sh:/opt/pamirs/run/run.sh \ -v $configDir/lib:/opt/pamirs/outlib harbor.oinone.top/oinone/designer:$version-allinone-full Step2.2.3 window环境修改参数 在文件中找到如下 set configDir=/d/shushi/docker/oinone-op-ds-all-full set version=4.6.28.3 set IP=192.168.0.121 修改configDir的路径((下载oinone-op-ds-xx.zip解压后的路径) 修改对应的镜像版本号 修改对应的IP为docker宿主机IP @echo off set configDir=/d/shushi/docker/oinone-op-ds-all-full set version=4.6.28.3 set IP=192.168.0.121 docker run -d –name designer-allinone ^ -e DUBBO_IP_TO_REGISTRY=%IP% ^ -e DUBBO_PORT_TO_REGISTRY=20880 ^ -p 8099:8091…

    2024年5月23日
    1.0K00
  • 4.1.4 模块之元数据详解

    介绍Module相关元数据,以及对应代码注解方式。大家还是可以通读下,以备不时之需 如您还不了解Module的定义,可以先看下2.3【oinone独特之源,元数据与设计原则】一文对Module的描述,本节主要带大家了解Module元数据构成,能让小伙伴非常清楚oinone从哪些维度来描述Module, 一、元数据说明 ModuleDefinition 元素数据构成 含义 对应注解 备注 displayName 显示名称 @Module( displayName=””, name=””, version=””, category=””, summary=””, dependencies={“”,””}, exclusions={“”,””}, priority=1L ) name 技术名称 latestVersion 安装版本 category 分类编码 summary 描述摘要 moduleDependencies 依赖模块编码列表 moduleExclusions 互斥模块编码列表 priority 排序 module 模块编码 @Module.module(“”) dsKey 逻辑数据源名 @Module.Ds(“”) excludeHooks 排除拦截器列表 @Module.Hook(excludes={“”,””}) website 站点 @Module.Advanced( website=”http://www.oinone.top”, author=”oinone”, description=”oinone”, application=false, demo=false, web=false, toBuy=false, selfBuilt=true, license=SoftwareLicenseEnum.PEEL1, maintainer=”oinone”, contributors=”oinone”, url=”http://git.com” ) author module的作者 description 描述 application 是否应用 demo 是否演示应用 web 是否web应用 toBuy 是否需要跳转到website去购买 selfBuilt 自建应用 license 许可证 默认PEEL1 可选范围: GPL2 GPL2ORLATER GPL3 GPL3ORLATER AGPL3 LGPL3 ORTHEROSI PEEL1 PPL1 ORTHERPROPRIETARY maintainer 维护者 contributors 贡献者列表 url 代码库的地址 boot 是否自动安装的引导启动项 @Boot 加上该注解代表: 启动时会自动安装,不管yml文件的modules是否配置 moduleClazz 模块定义所在类 只有用代码编写的模块才有 packagePrefix 包路径,用于扫描该模块下的其他元数据 dependentPackagePrefix 依赖模块列对应的扫描路径 state 状态 系统自动计算,无需配置 metaSource 元数据来源 publishCount 发布总次数 platformVersion 最新平台版本 本地与中心平台的版本对应。做远程更新时会用到 publishedVersion 最新发布版本 表4-1-4-1 ModuleDefinition UeModule 是对ModuleDefinition的继承,并扩展了跟前端交互相关的元数据 元素数据构成 含义 对应注解 备注 homePage Model 跳转模型编码 @UxHomepage(@UxRoute() 对应一个ViewAction,如果UxRoute只配置了模型,则默认到该模型的列表页 homePage Name 视图动作或者链接动作名称 logo 图标 @UxAppLogo(logo=””) 表4-1-4-2 UeModule 二、元数据,代码注解方式 Module Module ├── displayName 显示名称 ├── name 技术名称 ├── version 安装版本 ├── category 分类编码 ├── summary 描述摘要 ├── dependencies 依赖模块编码列表 ├── exclusions 互斥模块编码列表 ├── priority 排序 ├── module 模块编码 │ └── value ├── Ds 逻辑数据源名 │ └── value ├── Hook 排除拦截器列表…

    Oinone 7天入门到精通 2024年5月23日
    1.1K00

Leave a Reply

登录后才能评论