3.9.1.1. 管理动态属性

可以在 Administration>Dynamic Attributes 界面管理动态属性。界面的左边有类别列表,右边是属于选中分类的属性。

如果要给一个实体创建动态属性,首先需要创建一个分类。如果该实体类实现了 Categorized 接口,分类编辑器里面的 Default 复选框表示该分类会自动选为新实例的类型。如果实体没有实现 Categorized 接口,则不会用复选框的值,你可以自己为该实体创建单一类型,或者创建多个类型 - 实体的所有属性都会按照动态属性可见性设置展示。

在修改了动态属性配置之后,点击分类浏览部分的 Apply settings 按钮。改动也可以通过菜单的 Administration > JMX Console 调用 app-core.cuba:type=CachingFacade JMX bean 的 clearDynamicAttributesCache() 方法应用。

下面是类别编辑器的界面示例:

categoryEditor
Figure 38. 类别编辑界面

如果应用程序支持多种语言,则会显示 Name localization 分组框。它允许为每个可用的语言环境设置类别的本地化名称。

categoryLocalization
Figure 39. 本地化类别名称

Attributes Location 标签页,可以在 DynamicAttributesPanel 内设置每个动态属性的位置。

dynamic attributes location
Figure 40. 设置动态属性的位置

Columns count 下拉列表中指定列的数量。如要更改属性的位置,从属性列表拖拽该属性放置到目的行列的位置。也可以添加空的单元格或者更改属性的顺序。做完更改后,点击 Save configuration 按钮。

实体编辑器的 DynamicAttributesPanel 面板中属性的位置:

dynamic attributes location rezult

动态属性编辑界面可以设置属性的名称、系统代码、值类型、属性的默认值,以及验证脚本。

runtimePropertyEditor
Figure 41. 动态属性编辑界面

对于除 Boolean 以外的所有值类型,都有一个 Width 字段可用于设置 Form 中的字段宽度(以像素为单位或百分比)。如果 Width 字段为空,则假定其值为 100%。

对于除 Boolean 之外的所有值类型,还有一个 Is collection 复选框。允许为所选类型创建多值动态属性。

对于所有的数字类型:DoubleFixed-point numberInteger - 可以用下列字段: * Minimum value – 当输入属性值时,会检查属性值必须大于等于指定的最小值。 * Maximum value – 当输入属性值时,会检查属性值必须小于等于指定的最大值。

对于 Fixed-point number 值类型,可以使用 Number format pattern 字段设置格式模板。模板按照 DecimalFormat 介绍的规则设置。

对于所有的值类型,可以在 Validation script 字段设置脚本用于验证用户输入的值。验证逻辑在 Groovy 脚本中。如果 Groovy 验证失败,脚本应当返回一个错误消息。否则,脚本可以不返回任何值或者返回 null。被检查的值在脚本中可以使用 value 变量获取。错误消息使用一个 Groovy 字符串;其中可以用 $value 关键字来生成格式化的消息。

示例:

if (!value.startsWith("correctValue")) return "the value '\$value' is incorrect"

对于 Enumeration 值类型,通过列表编辑器在 Enumeration 字段中定义命名值集合。

runtimePropertyEnum
Figure 42. Enumeration 类型的动态属性编辑界面

每个枚举值可以进行本地化显示设置。

runtimePropertyEnumLocalization
Figure 43. Enumeration 类型动态属性本地化设置

对于 StringDoubleEntityFixed-point numberInteger 数据类型,可以使用 Lookup field 复选框。如果设置了该复选框,用户可以从下拉列表中选择属性值。可选值列表可在 Calculated values and options 标签页配置Entity 数据类型会配置 Where 和 Join 语句。

再看看 Calculated values and options 标签页。在 Attribute depends on 字段,可以设置当前属性依赖的其它属性。当改变其中一个依赖属性时,则会重新执行计算该属性值的脚本或者执行计算可能值列表的脚本。

计算属性值的 Groovy 脚本通过 Recalculation value script 字段设置。脚本必须返回一个新的参数值。脚本会收到下面这些参数:

  • entity – 编辑的实体;

  • dynamicAttributes – 一个 map 映射,key – 属性代码,value – 动态属性的值。

dynamic attributes recalculation
Figure 44. 值重算脚本

使用 dynamicAttributes map 重算脚本示例:

if (dynamicAttributes['PassengerNumberofseats'] > 9) return 'Bus' else return 'Passenger car'

脚本会在属性依赖的其它属性中任何一个发生变化时进行调用。

如果定义了脚本,属性的输入字段将变成不可编辑状态。

重算只能在这些 UI 组件有效:FormDynamicAttributesPanel

Options type 字段定义选项加载器的类型,如果 General 标签页的查找控件复选框选中,则必须选择 Options type。如果复选框没有选中,Options type 会不可用。

可用的选项加载器类型:Groovy、SQL、JPQL(仅对于 Entity 数据类型)。

  • Groovy 选项加载器会使用 Groovy 脚本加载值的列表。entity 变量会传递给脚本,因此可以在脚本中使用实体的属性(包括动态属性)。String 类型的属性脚本示例:

    dynamic attributes Groovy options
    Figure 45. Groovy 选项加载器的脚本
  • SQL 选项加载器使用 SQL 脚本加载选项值。可以在脚本中使用 ${entity} 变量访问实体。使用 ${entity.<field>} 访问实体参数,field 是实体参数的名称。+ 前缀可以用来访问实体的动态属性,比如 ${entity.+<field>}。脚本示例(这里我们访问实体和实体的动态属性 Categorytype):

    select name from DYNAMICATTRIBUTESLOADER_TAG
    where CUSTOMER_ID = ${entity}
    and NAME = ${entity.+Categorytype}
  • JPQL 选项加载器只能使用在 Entity 类型的动态属性。JPQL 条件通过 JoinClauseWhere Clause 字段设置。另外,可以使用 Constraint Wizard,能动态创建 JPQL 条件。在 JPQL 参数中可以使用 {entity}{entity.<field>}

所有类型的动态属性都支持本地化:

runtimePropertyLocalization
Figure 46. 动态属性本地化
动态属性的可见性

动态属性还可以设置可见性,定义在哪些界面中显示。默认情况下,动态属性不显示。

runtimePropertyVisibility
Figure 47. 动态属性可见性设置

除了界面之外,还可以为属性指定显示组件(比如,可以在界面中,指定多个Form组件显示同一实体的字段)。

如果该属性在界面上标记为可见,则在界面上用来展示相应实体的所有表单和表格中会自动显示该属性。

对动态属性的访问也受用户角色设置的限制。动态属性的安全设置与常规属性的安全设置类似。

动态属性可以手动添加到界面,给数据加载器添加 dynamicAttributes="true" 属性并使用带 + 前缀的动态属性代码绑定组件:

<data>
    <instance id="carDc" class="com.company.app.entity.Car" view="_local">
        <loader id="carDl" dynamicAttributes="true"/>
    </instance>
</data>
<layout>
    <form id="form"
          dataContainer="carDc">
        <!--...-->
        <textField property="+PassengerNumberofseats"/>
    </form>