entityPicker 实体选择器

支持用户从弹窗中选择单一 实体 实例并进行相关操作。操作可以是预定义的操作,例如更新实例的详细信息,或自定义的操作以完成其他一些任务。

  • XML 元素:entityPicker

  • Java 类:EntityPicker

基本用法

当字段值是实体对象时,通常使用 entityPicker 组件。支持用户选择特定实体实例并执行相关操作。

点击查找按钮可以打开一个显示实体实例 列表视图 的弹窗:

entity picker basic
entity picker basic 2

与应用程序中的其他视图一样,这个视图也是可以配置的,支持提供多个属性帮助用户找到需要的实体实例。与 entityComboBox 实体下拉框 相比能提供更多的上下文。

当实例数量较大时,会在浏览列表时动态加载其他实例。

简单用例

下面的示例演示如何使用 entityPicker 组件选择用户所属的部门:

该示例需要先为部门实体定义 列表视图
<data>
    <instance class="com.company.onboarding.entity.User" id="userDc"> (1)
        <fetchPlan extends="_base"> (2)
            <property name="department" fetchPlan="_base"/>
        </fetchPlan>
        <loader id="userDl"/>
    </instance>
</data>
<facets>
    <dataLoadCoordinator auto="true"/> (3)
</facets>
<layout>
    <entityPicker id="entityPicker"
                  dataContainer="userDc"
                  property="department"
                  label="Department"> (4)
        <actions>
            <action id="entityLookup" type="entity_lookup"/> (5)
            <action id="entityClear" type="entity_clear"/> (6)
        </actions>
    </entityPicker>
</layout>
1 保存当前正在编辑的 User 实例的数据容器。
2 扩展了 fetch plan,以获取 Department 实例集合作为选项。
3 数据加载协调器,自动为组件提供实例选项。
4 将组件与数据容器和属性绑定。
5 添加预定义操作,用于打开查找视图。
6 添加预定义操作,用于清除所选内容。

有关 entityPicker 及其变体的更多交互式示例,请参阅:

数据绑定

数据绑定是指将组件与数据容器进行关联。可视化组件或相应数据容器中的更改可以触发彼此的更新。有关详细信息,请参阅 使用数据组件

选择一个实例

如果只是简单的需要选择一个实体实例,那么可以通过 metaClass 属性指定实体:

<entityPicker metaClass="Department">
    //...
</entityPicker>

更新关联属性

选择实体实例通常用来更新另一个实体中的一个属性。在 上面的示例 中,通过选择 Department 实例更新了 User 实例中的部门属性。

此时,需要将组件绑定至父实体的数据容器,并指定需要更新的属性,这两个步骤分别通过 dataContainerproperty 属性实现:

<entityPicker dataContainer="userDc" property="department">
    //...
</entityPicker>

操作

可以给 entityPicker 设置自定义或预定义的操作,操作作为按钮显示在右侧。 定义操作可以在 XML 中用 actions 元素或者在控制器中用 addAction() 方法编程式添加。

如需在 Jmix Studio 中添加 action,可以在界面 XML 或者 Jmix UI 结构面板中选择组件,然后点击组件面板的 Add 按钮。

预定义操作

当 Studio 在详情视图中生成 entityPicker 时,还会同时生成两个预定义的操作:entity_lookupentity_clear。此外,还支持 entity_openentity_openComposition 操作。

typeid 属性在 XML 中配置预定义操作。

如果创建无操作的 entityPicker,XML 加载器仅定义 entity_lookupentity_clear 操作。如需添加其他预定义操作,例如,entity_open,可以按照下面这样指定 actions 元素:

<entityPicker dataContainer="userDc"
              property="department"
              label="Department" >
    <actions>
        <action id="entityLookup" type="entity_lookup"/>
        <action id="entityClear" type="entity_clear"/>
        <action id="entityOpen" type="entity_open"/>
    </actions>
</entityPicker>

actions 元素不是对标准操作进行扩展,而是进行覆盖。因此,需要明确定义所有必需操作的标识符。

自定义操作

如需在 XML 中定义自定义操作,可以使用内部的 actions 元素。为 action 指定 idicon 属性:

<entityPicker id="departmentEntityPicker"
              dataContainer="userWithDeptManagerDc"
              property="department">
    <actions>
        <action id="entityLookup" type="entity_lookup"/>
        <action id="knowManager" icon="QUESTION"
                description="Know HR-manager"/>
    </actions>
</entityPicker>

然后在视图控制器订阅 Action.ActionPerformedEvent 实现自定义逻辑:

@ViewComponent
private EntityPicker<Department> departmentEntityPicker;

@Autowired
private Notifications notifications;

@Subscribe("departmentEntityPicker.knowManager")
public void onKnowManager(ActionPerformedEvent event) {
    Department department = departmentEntityPicker.getValue();
    if (department != null)
        notifications.create(department.getName() + " has "
                + department.getHrManager() + " HR-manager")
                .show();
    else notifications.create("Choose a department").show();
}

可以用 Studio 生成处理 Action.ActionPerformedEvent 的桩代码。

编程式添加操作

使用 addAction() 以编程方式添加操作。

  • 添加标准操作

    例如,如果在组件的 XML 描述中没有内部的 actions 元素,就可以使用这个方法添加缺少的标准操作:

    @ViewComponent
    private EntityPicker<Department> departmentEntityPicker;
    
    @Autowired
    private Actions actions;
    
    @Subscribe
    public void onInit(InitEvent event) {
        departmentEntityPicker.addAction(actions.create(EntityOpenAction.ID));
    }
  • 添加自定义操作

    创建自定义操作的示例:

    @ViewComponent
    private EntityPicker<Department> departmentEntityPicker;
    
    @Subscribe
    public void onInit(InitEvent event) {
        departmentEntityPicker.addAction(new BaseAction("showManager")
                .withIcon(VaadinIcon.QUESTION_CIRCLE)
                .withHandler(e -> {
                    Department department = departmentEntityPicker.getValue();
                    if (department != null)
                        notifications.create(department.getName() + " has "
                                        + department.getHrManager() + " HR-manager")
                                .show();
                    else notifications.create("Choose a department").show();
                }));
    }

XML 属性

metaClass

可以在不绑定数据容器的情况下使用 entityPicker,即不设置 dataContainerproperty 属性。在这种情况下,需要使用 metaClass 属性指定 entityPicker 的实体类型。示例:

<entityPicker metaClass="Department">
    <actions>
        <action id="entityLookup" type="entity_lookup"/>
        <action id="entityOpen" type="entity_open"/>
    </actions>
</entityPicker>

可以通过将组件注入控制器并调用其 getValue() 方法来获取所选实体的实例。

事件和处理器

在 Jmix Studio 生成处理器桩代码时,可以使用 Jmix UI 组件面板的 Handlers 标签页或者视图类顶部面板的 Generate Handler 添加,也可以通过 CodeGenerate 菜单(Alt+Insert / Cmd+N)生成。

XML 内部元素