entityPicker

Поле ввода для выбора экземпляра сущности через диалоговое окно и выполнения над ним различных действий. Это могут быть как предопределенные действия, такие как обновление информации об экземпляре, так и пользовательские, настраиваемые действия для выполнения более специфических задач.

  • XML-элемент: entityPicker

  • Java-класс: EntityPicker

Основы

Компонент entityPicker обычно используется, когда значение поля должно представлять собой ссылку на сущность. Он сочетает в себе возможность выбора конкретного экземпляра сущности с возможностью выполнения соответствующих действий.

Нажатие на кнопку выбора открывает диалоговое окно с экраном списка, содержащим экземпляры сущности.

entity picker basic
entity picker basic 2

Как и другие экраны в приложении, этот экран является настраиваемым и позволяет отображать несколько атрибутов, чтобы пользователи могли легко идентифицировать нужный экземпляр. Оно предоставляет больше контекста по сравнению с entityComboBox, который показывает только названия экземпляров.

Если количество экземпляров велико, дополнительные элементы загружаются динамически при прокрутке списка.

Быстрый старт

Следующий пример демонстрирует, как использовать компонент entityPicker для выбора отдела, к которому принадлежит пользователь:

Для корректной работы примера убедитесь, что определили экран списка для сущности Department.
<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 Фетч-план расширен для получения коллекции экземпляров Department, которые будут доступны для выбора.
3 Координатор загрузки данных для автоматического предоставления компоненту экземпляров для выбора.
4 Привязка компонента к контейнеру данных и свойству.
5 Добавление предопределенного действия для открытия экрана выбора.
6 Добавление предопределенного действия для очистки выбора.

Для получения более интерактивных примеров entityPicker и его вариаций смотрите:

Привязка данных

Привязка данных относится к связыванию визуального компонента с контейнером данных. Изменения в визуальном компоненте или соответствующем контейнере данных могут вызывать обновления друг друга. Подробности смотрите в разделе Использование компонентов данных.

Выбор экземпляра

Если вам просто нужен способ выбора экземпляра определенной сущности, укажите эту сущность, используя атрибут metaClass:

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

Выбор экземпляра для обновления связанного атрибута

Выбор экземпляра часто предназначен для обновления атрибута в другом экземпляре. В примере выше выбор экземпляра Department обновляет экземпляр User, связывая его с выбранным отделом.

В таких случаях вам нужно будет привязать компонент к контейнеру данных, содержащему экземпляр, и указать атрибут для обновления, используя dataContainer и property соответственно:

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

Действия

Вы можете определить пользовательские и предопределенные действия для entityPicker, отображаемые в виде кнопок справа. Это можно сделать либо в XML-дескрипторе, используя вложенный элемент actions, либо программно в контроллере, используя метод addAction().

Чтобы добавить действие в Jmix Studio, выберите компонент в XML-дескрипторе экрана или в панели структуры Jmix UI и нажмите кнопку Add в панели инспектора Jmix UI.

Предопределенные действия

Когда Studio генерирует entityPicker в экране деталей, он также генерирует два предопределенных стандартных действия: entity_lookup и entity_clear. Существуют также действия entity_open и entity_openComposition.

Используйте атрибуты type и id для объявления предопределенного действия в XML.

Если вы создаете entityPicker без действий, загрузчик XML определит только действия entity_lookup и entity_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. Укажите атрибуты id и icon для действия:

<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>

Затем реализуйте пользовательскую логику в контроллере экрана, подписавшись на 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();
}

Вы можете сгенерировать заглушку обработчика ActionPerformedEvent с помощью Jmix Studio.

Добавление действий программно

Используйте метод 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();
                }));
    }

Атрибуты

metaClass

Вы можете использовать entityPicker без привязки к контейнеру данных, то есть без установки dataContainer и property. В этом случае следует использовать атрибут metaClass для указания типа сущности для entityPicker. Например:

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

Вы можете получить экземпляр выбранной сущности, инжектировав компонент в контроллер и вызвав его метод getValue().

Обработчики

Чтобы сгенерировать заглушку обработчика в Jmix Studio, используйте вкладку Handlers панели инспектора Jmix UI, или команду Generate Handler, доступную на верхней панели контроллера экрана и через меню CodeGenerate (Alt+Insert / Cmd+N).

Элементы