3.5.2.3 构建View的Layout

在日常需求中也经常需要调整Layout的情况,如出现树表结构(左树右表、级联),我们则需要通过修改View的Layout来完成。今天就带您学习下Layout的自定义

第一个表格Layout

如果我们想去除表格视图区域的搜索区、ActionBar(操作区),就可以为视图自定义一个简单的Layout就行啦

Step1 新建一个表格的Layout

在views/demo_core/layout路径下增加一个名为sample_table_layout.xml文件,name设置为sampleTableLayout

<view type="TABLE" name="sampleTableLayout">
<!--    <view type="SEARCH">-->
<!--        <pack widget="fieldset">-->
<!--            <element widget="search" slot="search" slotSupport="field"/>-->
<!--        </pack>-->
<!--    </view>-->
    <pack widget="fieldset" style="height: 100%" wrapperStyle="height: 100%">
        <pack widget="row" style="height: 100%; flex-direction: column">
<!--            <pack widget="col" mode="full" style="flex: 0 0 auto">-->
<!--                <element widget="actionBar" slot="actionBar" slotSupport="action">-->
<!--                    <xslot name="actions" slotSupport="action" />-->
<!--                </element>-->
<!--            </pack>-->
            <pack widget="col" mode="full" style="min-height: 234px">
                <element widget="table" slot="table" slotSupport="field">
                    <xslot name="fields" slotSupport="field" />
                    <element widget="rowAction" slot="rowActions" slotSupport="action"/>
                </element>
            </pack>
        </pack>
    </pack>
</view>

图3-5-2-27 新建一个表格的Layout

Step2 修改宠物达人自定义表格Template

在view标签上增加layout属性值为"sampleTableLayout"

<view name="tableView" model="demo.PetTalent" cols="1" type="TABLE" enableSequence="true" layout="sampleTableLayout">
……省略其他
</view>

图3-5-2-28 修改宠物达人自定义表格Template

Step3 重启看效果

image.png

图3-5-2-29 示例效果

Step4 修改宠物达人自定义表格Template

去除在view标签上的layout属性配置,让其回复正常

第一个树表Layout

本节以“给商品管理页面以树表的方式增加商品类目过滤”为例

Step1 增加商品类目模型

增加PetItemCategory模型继承CodeModel,新增两个字段定义name和parent,其中parent字段M2O关联自身模型,非必填字段(如字段值为空即为一级类目):

package pro.shushi.pamirs.demo.api.model;

import pro.shushi.pamirs.meta.annotation.Field;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.base.common.CodeModel;

@Model.model(PetItemCategory.MODEL_MODEL)
@Model(displayName = "宠物商品类目",summary="宠物商品类目",labelFields={"name"})
public class PetItemCategory extends CodeModel {

    public static final String MODEL_MODEL="demo.PetItemCategory";
    @Field(displayName = "类目名称",required = true)
    private String name;

    @Field(displayName = "父类目")
    @Field.many2one
    private PetItemCategory parent;
}

图3-5-2-30 增加商品类目模型

Step2 修改自定义商品模型

为商品模型PetItem增加一个category字段m2o关联PetItemCategory

@Field(displayName = "类目")
@Field.many2one
private PetItemCategory category;

图3-5-2-31 修改宠物商品模型

Step3 新增名为treeTableLayout的Layout

在views/demo_core/layout路径下增加一个名为tree_table_layout.xml文件,name设置为treeTableLayout

image.png

图3-5-2-32 新增名为treeTableLayout的Layout

<view type="TABLE" name="treeTableLayout">
  <view type="SEARCH">
    <pack widget="fieldset">
      <element widget="search" slot="search" slotSupport="field"/>
    </pack>
  </view>
  <pack widget="fieldset" style="height: 100%" wrapperStyle="height: 100%">
    <pack widget="row" wrap="false" style="height: 100%">
      <pack widget="col" mode="full" style="min-width: 257px; max-width: 257px">
        <pack widget="fieldset" style="height: 100%" wrapperStyle="height: 100%; padding: 24px 16px">
          <pack widget="col" style="height: 100%">
            <element widget="tree" slot="tree" style="height: 100%" />
          </pack>
        </pack>
      </pack>
      <pack widget="col" mode="full" style="min-width: 400px">
        <pack widget="row" style="height: 100%; flex-direction: column">
          <pack widget="col" mode="full" style="width: 100%; flex: 0 0 auto">
            <element widget="actionBar" slot="actionBar" slotSupport="action">
              <xslot name="actions" slotSupport="action" />
            </element>
          </pack>
          <pack widget="col" mode="full" style="width: 100%; min-height: 345px">
            <element widget="table" slot="table" slotSupport="field">
              <xslot name="fields" slotSupport="field" />
              <element widget="rowAction" slot="rowActions" slotSupport="action" />
            </element>
          </pack>
        </pack>
      </pack>
    </pack>
  </pack>
</view>

图3-5-2-33 treeTableLayout的示例代码

Step4 自定义商品管理的Template

  1. 在views/demo_core/template路径下增加一个名为pet_item_table.xml文件

  2. 跟普通自定义template的区别在于

a. 配置layout属性为【treeTableLayout】跟前面layout定义一致

b. 配置了widget为tree的template节点,node可以配置多个,node配置说明如下

ⅰ. model,模型编码,必填。

ⅱ. label,数据标题,支持表达式,必填。

ⅲ. labelFields,数据标题中使用的字段列表,必填。

ⅳ. references,层级关联字段,第一层无效,其他层必填。模型编码#字段。

ⅴ. selfReferences,自关联字段,模型编码#字段。

ⅵ. search,点击搜索字段,必须使用主表格字段。模型编码#字段。

ⅶ. filter,层级过滤条件。模型编码#字段。

以上所有使用#拼接的属性配置,与model一致的情况下,均可以省略模型编码。

image.png

图3-5-2-34 pet_item_table.xml示例代码图

<view name="tableView" model="demo.PetItem"  type="TABLE" cols="1" enableSequence="false" layout="treeTableLayout">
  <template slot="actions" autoFill="true"/>
  <template slot="rowActions" autoFill="true"/>
  <template slot="fields">
    <field invisible="true" priority="5" data="id" label="ID" readonly="true"/>
    <field priority="90" data="code" label="编码"/>
    <field priority="101" data="itemName" label="商品名称"/>
    <field priority="101" data="dataStatus" label="数据状态">
      <options>
        <option name="DRAFT" displayName="草稿" value="DRAFT" state="ACTIVE"/>
        <option name="NOT_ENABLED" displayName="未启用" value="NOT_ENABLED" state="ACTIVE"/>
        <option name="ENABLED" displayName="已启用" value="ENABLED" state="ACTIVE"/>
        <option name="DISABLED" displayName="已禁用" value="DISABLED" state="ACTIVE"/>
      </options>
    </field>
    <field priority="102" data="price" label="商品价格"/>
    <field priority="103" data="shop" label="店铺">
      <options>
        <option references="demo.PetShop" referencesType="STORE" referencesLabelFields="shopName">
          <field name="shopName" data="shopName" ttype="STRING"/>
        </option>
      </options>
    </field>
    <field priority="104" data="shopId" label="店铺id"/>
    <field priority="105" data="type" label="品种">
      <options>
        <option references="demo.PetType" referencesType="STORE" referencesLabelFields="name">
          <field name="name" data="name" ttype="STRING"/>
        </option>
      </options>
    </field>
    <field priority="106" data="typeId" label="品种类型"/>
    <field priority="107" data="petItemDetails" label="详情">
      <options>
        <option references="demo.PetItemDetail" referencesType="TRANSIENT" referencesLabelFields="remark">
          <field name="remark" data="remark" ttype="STRING"/>
        </option>
      </options>
    </field>
    <field priority="108" data="tags" label="商品标签"/>
    <field priority="109" data="petTalents" label="推荐达人">
      <options>
        <option references="demo.PetTalent" referencesType="STORE" referencesLabelFields="name">
          <field name="name" data="name" ttype="STRING"/>
        </option>
      </options>
    </field>
    <field priority="200" data="createDate" label="创建时间" readonly="true"/>
    <field priority="210" data="writeDate" label="更新时间" readonly="true"/>
    <field priority="220" data="createUid" label="创建人id"/>
    <field priority="230" data="writeUid" label="更新人id"/>
  </template>
  <template slot="search" autoFill="true" cols="4"/>
  <template enableSearch="true" slot="tree" style="height: 100%" widget="tree">
    <nodes>
<!--       <node label="activeRecord.name" labelFields="name" model="demo.PetItemCategory" search="demo.PetItem#category" selfReferences="parent"/> -->
           <node label="activeRecord.name" labelFields="name" model="demo.PetItemCategory" search="demo.PetItem#category" selfReferences="demo.PetItemCategory#parent"/>
     </nodes>
   </template>
 </view>

图3-5-2-35 pet_item_table.xml示例代码

Step5 为商品类目增加管理入口

修改DemoMenus类,增加类目管理菜单

image.png

图3-5-2-36 增加类目管理菜单

@UxMenu("类目管理")@UxRoute(PetItemCategory.MODEL_MODEL) class PetItemCategoryMenu{
}

图3-5-2-37 增加类目管理菜单代码

Step6 重启看效果

  1. 进入类目管理页面,新增商品类目数据

image.png

图3-5-2-38 示例效果

  1. 进入商品管理页面,找一行数据修改其类目字段,然后再点击左边树看过滤效果

image.png

图3-5-2-39 示例效果

第一个级联Layout

本节以“给商品管理页面以级联的方式增加商品类目过滤”为例,该例子中左边级联项由多个模型组成

Step1 增加商品类目类型模型

增加PetItemCategoryType模型集成CodeModel,新增两个字段定义name

package pro.shushi.pamirs.demo.api.model;

import pro.shushi.pamirs.meta.annotation.Field;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.base.common.CodeModel;

@Model.model(PetItemCategoryType.MODEL_MODEL)
@Model(displayName = "宠物商品类目类型",summary="宠物商品类目类型",labelFields={"name"})
public class PetItemCategoryType extends CodeModel {

    public static final String MODEL_MODEL="demo.PetItemCategoryType";
    @Field(displayName = "类目类型名称",required = true)
    private String name;

}

图3-5-2-40 增加PetItemCategoryType模型集成CodeModel

Step2 修改商品类目

为商品类目模型PetItemCategory增加一个type字段m2o关联PetItemCategoryType

@Field(displayName = "类目类型")
@Field.many2one
private PetItemCategoryType type;

图3-5-2-41 为商品类目模型PetItemCategory增加一个type字段

Step3 新增名为cascaderTableLayout的Layout

在views/demo_core/layout路径下增加一个名为cascader_table_layout.xml文件

image.png

图3-5-2-42 新增名为cascaderTableLayout的Layout

<view type="TABLE" name="cascaderTableLayout">
<view type="SEARCH">
    <pack widget="fieldset">
        <element widget="search" slot="search" slotSupport="field"/>
    </pack>
</view>
<pack widget="fieldset" style="height: 100%" wrapperStyle="height: 100%; overflow: auto">
    <pack widget="row" wrap="false" style="height: 100%">
        <pack widget="col" mode="full" style="flex: unset">
            <element widget="card-cascader" slot="cardCascader" style="height: 100%" />
        </pack>
        <pack widget="col" mode="full" style="min-width: 564px">
            <pack widget="row" style="height: 100%; flex-direction: column">
                <pack widget="col" mode="full" style="width: 100%; flex: 0 0 auto">
                    <element widget="actionBar" slot="actionBar" slotSupport="action">
                        <xslot name="actions" slotSupport="action" />
                    </element>
                </pack>
                <pack widget="col" mode="full" style="width: 100%; min-height: 345px">
                    <element widget="table" slot="table" slotSupport="field">
                        <xslot name="fields" slotSupport="field" />
                        <element widget="rowAction" slot="rowActions" slotSupport="action"/>
                    </element>
                </pack>
            </pack>
        </pack>
    </pack>
</pack>
</view>

图3-5-2-43 代码说明

Step4 修改商品管理的Template

  1. 修改在views/demo_core/template路径下名为pet_item_table.xml的文件

a. 配置layout属性为【cascaderTableLayout】跟前面layout定义一致

b. 配置了widget为card-cascader的template节点,node可以配置多个,node配置跟树表的配置一致

<view name="tableView" model="demo.PetItem"  type="TABLE" cols="1" enableSequence="false" layout="cascaderTableLayout">
  <template slot="actions" autoFill="true"/>
  <template slot="rowActions" autoFill="true"/>
  <template slot="fields">
    <field invisible="true" priority="5" data="id" label="ID" readonly="true"/>
    <field priority="90" data="code" label="编码"/>
    <field priority="101" data="itemName" label="商品名称"/>
    <field priority="101" data="dataStatus" label="数据状态">
      <options>
        <option name="DRAFT" displayName="草稿" value="DRAFT" state="ACTIVE"/>
        <option name="NOT_ENABLED" displayName="未启用" value="NOT_ENABLED" state="ACTIVE"/>
        <option name="ENABLED" displayName="已启用" value="ENABLED" state="ACTIVE"/>
        <option name="DISABLED" displayName="已禁用" value="DISABLED" state="ACTIVE"/>
      </options>
    </field>
    <field priority="102" data="price" label="商品价格"/>
    <field priority="103" data="shop" label="店铺">
      <options>
        <option references="demo.PetShop" referencesType="STORE" referencesLabelFields="shopName">
          <field name="shopName" data="shopName" ttype="STRING"/>
        </option>
      </options>
    </field>
    <field priority="104" data="shopId" label="店铺id"/>
    <field priority="105" data="type" label="品种">
      <options>
        <option references="demo.PetType" referencesType="STORE" referencesLabelFields="name">
          <field name="name" data="name" ttype="STRING"/>
        </option>
      </options>
    </field>
    <field priority="106" data="typeId" label="品种类型"/>
    <field priority="107" data="petItemDetails" label="详情">
      <options>
        <option references="demo.PetItemDetail" referencesType="TRANSIENT" referencesLabelFields="remark">
          <field name="remark" data="remark" ttype="STRING"/>
        </option>
      </options>
    </field>
    <field priority="108" data="tags" label="商品标签"/>
    <field priority="109" data="petTalents" label="推荐达人">
      <options>
        <option references="demo.PetTalent" referencesType="STORE" referencesLabelFields="name">
          <field name="name" data="name" ttype="STRING"/>
        </option>
      </options>
    </field>
    <field priority="200" data="createDate" label="创建时间" readonly="true"/>
    <field priority="210" data="writeDate" label="更新时间" readonly="true"/>
    <field priority="220" data="createUid" label="创建人id"/>
    <field priority="230" data="writeUid" label="更新人id"/>
  </template>
  <template slot="search" autoFill="true" cols="4"/>
  <template enableSearch="true" slot="cardCascader" style="height: 100%" widget="card-cascader">
      <nodes>
          <node label="activeRecord.name" title="类目类型" labelFields="name" model="demo.PetItemCategoryType" />
          <node label="activeRecord.name" title="类目" labelFields="name" model="demo.PetItemCategory" search="demo.PetItem#category" references="demo.PetItemCategory#type" selfReferences="demo.PetItemCategory#parent"/>
      </nodes>
  </template>
</view>

图3-5-2-44 修改商品管理的Template

Step5 为商品类目类型增加管理入口

image.png

图3-5-2-45 为商品类目类型增加管理入口

@UxMenu("类目类型")@UxRoute(PetItemCategoryType.MODEL_MODEL) class PetItemCategoryTypeMenu{
}

图3-5-2-46 代码示例

Step6 重启看效果

  1. 进入类目类型管理页面,新增商品类目类型数据

image.png

图3-5-2-47 进入类目类型管理页面

  1. 进入类目管理页面,修改一级类目的类型

image.png

图3-5-2-48 修改一级类目的类型

  1. 进入商品管理页面,找一行数据修改其类目字段,然后再点击左边级联项看过滤效果

image.png

图3-5-2-49 进入商品管理页面

树表与级联的更多配置

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

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

Like (0)
史, 昂's avatar史, 昂数式管理员
Previous 2024年5月23日 am9:24
Next 2024年5月23日 am9:26

相关推荐

  • 开放平台

    1. 开放介绍 开放平台是将 Oinone 平台内的能力向外开放,如开放商品信息查询接口、发货单查询接口等。 包括开放接口、三方应用管理。 2. 开放接口 管理开放接口信息,基本操作包括:新增、编辑、停用/启用。 2.1. 新增接口 定义API名称,选择业务域、关联模型,方法支持GET/POST/PUT/DELETE,配置接口参数、响应结果等信息。 2.2. 编辑接口 编辑需要填写的内容同新增,不做赘述。 2.3. 停用/启用 新增后为已启用,停用后,API将无法访问,请慎重使用;针对停用的API进行启用。 3. 应用管理 管理开放接口集成的外部应用,基本操作包括:新增、查看密钥、授权调整、停用/启用。 3.1. 新增应用 新增应用时,输入应用名称,选择数据传输加密算法AES密钥或RSA公钥,勾选授权的API接口。 3.2. 停用/启用 新增后为已启用,停用后,应用将无法访问授权的接口,请慎重使用;针对停用的应用可进行启用。 3.3. 查看密钥 点击【查看密钥】,弹窗展示当前 API Secret,支持复制。 3.4. 授权调整 指调整当前应用的授权的API 范围。

    2024年6月20日
    2.6K00
  • 3.3 Oinone以模型为驱动

    模型(model):Oinone一切从模型出发,是数据及对行为的载体: 是对所需要描述的实体进行必要的简化,并用适当的变现形式或规则把它的主要特征描述出来所得到的系统模仿品。模型由元信息、字段、数据管理器和自定义函数构成; 符合面向对象设计原则包括:封装、继承、多态。 本章会带大家快速而全方位地认识Oinone的模型。会从以下几个维度去对模型展开详细介绍。 构建第一个Model 模型的类型 模型的数据管理器 模型的继承 模型编码生成器 枚举与数据字典 字段序列化方式 字段类型之基础与复合 字段类型之关系与引用

    Oinone 7天入门到精通 2024年5月23日
    1.7K00
  • 3.5.4 Ux注解详解

    我们默认视图已经基本可以用了,但实际业务中还是会有一些不大不小的自定义需求,写自定义视图又太麻烦,今天我们来学习一种更加轻量的模式即:后端研发可以通过注解来配置视觉交互。该系列注解以Ux开头,例如@UxHomepage、@UxMenu、@UxAction、@UxView、@UxWidget等等。 视图XML的配置优先级大于在代码上的注解,也就是代码上的注解影响的是默认展示逻辑。 一、Ux家族图谱 我们先简单通过家族图谱做个简单了解,脑海里有一个影响当有需要的时候知道能不能做,深入了解还需要大家多多动手去尝试 图3-5-4-1 Ux家族图谱 二、默认视图后端配置举例 在下面的代码片段中UxTable、UxForm、UxDetail、UxTableSearch都有涉及,几个特殊点做些解释其他的留大家自行测试 Group分组的配置逻辑:为了不让一个分组内的字段不断的写Group,所以采取了第一个字段写了Group,到下一个出现的group之间的字段都自动归为一个Group 搜素整体不展示可以用“@UxTable(enableSearch = false)”配置在模型的类上。 字段搜索用“UxTableSearch”配置在模型的字段上,其特殊逻辑是只要你配了一个字段,系统就不自动补充了,例子中表格页的搜索栏只会留下店铺名称和店铺编码 ……其他代码 //@UxTable(enableSearch = false),整体不支持搜索 public class PetShop extends AbstractDemoIdModel { public static final String MODEL_MODEL="demo.PetShop"; @Field(displayName = "店铺编码") @UxForm.FieldWidget(@UxWidget(group = "Form基础数据"))//Form分组 @UxTableSearch.FieldWidget(@UxWidget())//支持搜索 private String code; @Field(displayName = "店铺编码2") @Field.Sequence(sequence = "DATE_ORDERLY_SEQ",prefix = "C",size=6,step=1,initial = 10000,format = "yyyyMMdd") private String codeTwo; @UxTableSearch.FieldWidget(@UxWidget())//支持搜索 @UxTable.FieldWidget(@UxWidget(invisible = "true"))//表格中不展示支持搜索 @Field(displayName = "店铺名称",required = true,immutable=true) private String shopName; @Field(displayName = "一年内新店") @UxForm.FieldWidget(@UxWidget(widget = "Switch",group = "Form基础数据"))//Switch,Checkbox可以切换着看,字段可选widget参考【字段的配置】一文 private Boolean oneYear; @Field(displayName = "开店时间",required = true) @UxDetail.FieldWidget(@UxWidget(invisible = "true"))//详情不展示 private Time openTime; @Field(displayName = "闭店时间",required = true) @UxDetail.FieldWidget(@UxWidget(invisible = "true"))//详情不展示 private Time closeTime; …… 其他代码 } 图3-5-4-2 默认视图后端配置举例

    2024年5月23日
    2.1K00
  • 4.1.17 框架之网关协议-GraphQL协议

    GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。 一个 GraphQL 服务是通过定义类型和类型上的字段来创建的,然后给每个类型上的每个字段提供解析函数。例如,一个 GraphQL 服务告诉我们当前登录用户是 me,这个用户的名称可能像这样: type Query { me: User } type User { id: ID name: String } 图4-1-17-1 GraphQL定义类型和字段示意 一并的还有每个类型上字段的解析函数: function Query_me(request) { return request.auth.user; } function User_name(user) { return user.getName(); } 图4-1-17-2 每个类型上字段的解析函数示意 一旦一个 GraphQL 服务运行起来(通常在 web 服务的一个 URL 上),它就能接收 GraphQL 查询,并验证和执行。接收到的查询首先会被检查确保它只引用了已定义的类型和字段,然后运行指定的解析函数来生成结果。 例如这个查询: { me { name } } 图4-1-17-3 GraphQL查询请求示意 会产生这样的JSON结果: { "me": { "name": "Luke Skywalker" } } 图4-1-17-4 GraphQL查询结果示意 了解更多 https://graphql.cn/learn/

    Oinone 7天入门到精通 2024年5月23日
    1.5K00
  • 4.1.14 Search之非存储字段条件

    search默认查询的是模型的queryPage函数,但我们有时候需要替换调用的函数,这个特性会在下个版本支持。其核心场景为当搜索条件中有非存储字段,如果直接用queryPage函数的rsql拼接就会报错,所以非存储字段不会增加在rsql中。本文介绍一个比较友好的临时替代方案。 非存储字段条件(举例) Step1 为PetTalent新增一个非存储字段unStore @Field(displayName = "非存储字段测试",store = NullableBoolEnum.FALSE) private String unStore; 图4-1-14-1 为PetTalent新增一个非存储字段unStore Step2 修改PetTalent的Table视图的Template 在标签内增加一个查询条件 <field data="unStore" /> 图4-1-14-2 修改PetTalent的Table视图的Template Step3 重启看效果 进入宠物达人列表页,在搜索框【非存储字段测试】输入查询内容,点击搜索跟无条件一致 Step4 修改PetTalentAction的queryPage方法 package pro.shushi.pamirs.demo.core.action; …… 引入依赖类 @Model.model(PetTalent.MODEL_MODEL) @Component public class PetTalentAction { ……其他代码 @Function.Advanced(type= FunctionTypeEnum.QUERY) @Function.fun(FunctionConstants.queryPage) @Function(openLevel = {FunctionOpenEnum.API}) public Pagination<PetTalent> queryPage(Pagination<PetTalent> page, IWrapper<PetTalent> queryWrapper){ QueryWrapper<PetTalent> queryWrapper1 = (QueryWrapper<PetTalent>) queryWrapper; Map<String, Object> queryData = queryWrapper.getQueryData(); String unStore = (String) queryData.get(LambdaUtil.fetchFieldName(PetTalent::getUnStore)); if (StringUtils.isNotEmpty(unStore)) { //转换查询条件 queryWrapper1.like( 图4-1-14-3 修改PetTalentAction的queryPage方法 Step5 重启看效果 在搜索框【非存储字段测试】输入查询内容,跟通过【达人】字段搜索的效果是一致的 图4-1-14-4 示例效果

    2024年5月23日
    2.3K00

Leave a Reply

Please Login to Comment