entityComboBox
Поле ввода для выбора экземпляра сущности из выпадающего списка с возможностью выполнения связанных действий. Поддерживаются как предопределённые действия (например, обновление данных экземпляра), так и пользовательские операции для решения специфических задач.
Этот компонент, по сути, является гибридом компонентов comboBox и entityPicker.
-
XML-элемент:
entityComboBox
-
Java-класс:
EntityComboBox
Основы
Компонент entityComboBox
обычно используется, когда значение поля должно представлять собой ссылку на сущность. Он позволяет пользователям выбирать конкретный экземпляр сущности с возможностью выполнения соответствующих действий.
Щелчок по полю или кнопке со стрелкой открывает выпадающий список, содержащий все существующие экземпляры сущности:
![]() |
![]() |
Обратите внимание, что если вы не настроили ленивую загрузку (lazy loading), компонент загрузит список всех доступных экземпляров как в память браузера, так и в память сервера. Это может потребить значительные системные ресурсы и повлиять на производительность, особенно при большом количестве элементов. Кроме того, пользователям может быть сложно найти конкретный экземпляр в длинном выпадающем списке.
Если ожидаемое количество элементов велико, например, тысячи или больше, или если выбор требует предоставления дополнительного контекста о каждом элементе, рекомендуется использовать entityPicker. |
Быстрый старт
Следующий пример демонстрирует, как использовать компонент entityCombobox
для выбора отдела, к которому принадлежит пользователь:
<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>
<collection class="com.company.onboarding.entity.Department"
id="departmentsDc"> (3)
<fetchPlan extends="_base"/>
<loader id="departmentsDl">
<query>
<![CDATA[select e from Department e]]>
</query>
</loader>
</collection>
</data>
<facets>
<dataLoadCoordinator auto="true"/> (4)
</facets>
<layout>
<entityComboBox dataContainer="userDc"
property="department"
itemsContainer="departmentsDc"> (5)
<actions>
<action id="entityClear" type="entity_clear"/> (6)
</actions>
</entityComboBox>
</layout>
1 | Контейнер данных для хранения экземпляра User , который в данный момент редактируется. |
2 | Фетч-план расширен для получения коллекции экземпляров Department , которые будут доступны для выбора. |
3 | Контейнер данных для хранения коллекции всех существующих экземпляров Department . |
4 | Координатор загрузки данных для автоматического предоставления компоненту экземпляров для выбора. |
5 | Привязка компонента к контейнеру данных и свойству. Указание контейнера, содержащего список элементов для выбора. |
6 | Добавление предопределенного действия для очистки выбора. |
Для более интерактивных примеров entityComboBox
и его вариантов смотрите:
Привязка данных
Привязка данных относится к связыванию визуального компонента с контейнером данных. Изменения в визуальном компоненте или соответствующем контейнере данных могут вызывать обновления друг друга. Подробности смотрите в разделе Использование компонентов данных.
Выбор экземпляра
Если вам просто нужно выбрать экземпляр конкретной сущности, укажите эту сущность, используя атрибут metaClass
. Чтобы указать коллекцию экземпляров для выбора, используйте атрибут itemsContainer.
<entityComboBox metaClass="Department"
itemsContainer="departmentsDc">
// ...
</entityComboBox>
Выбор экземпляра для обновления связанного атрибута
Выбор экземпляра часто предназначен для обновления атрибута в другом экземпляре. В примере выше, выбор экземпляра Department
обновляет экземпляр User
, связывая его с выбранным отделом.
В таких случаях вам нужно будет привязать компонент к контейнеру данных, содержащему экземпляр, и указать атрибут для обновления, используя атрибуты dataContainer и property соответственно. Чтобы указать коллекцию экземпляров для выбора, используйте атрибут itemsContainer.
<entityComboBox dataContainer="userDc"
property="department"
itemsContainer="departmentsDc">
// ...
</entityComboBox>
Действия
Изначально entityComboBox
не имеет никаких действий. Вам нужно добавить их явно, например:
<entityComboBox dataContainer="userDc"
property="department"
itemsContainer="departmentsDc">
<actions>
<action id="entityClear" type="entity_clear"/>
<action id="entityLookup" type="entity_lookup"/>
<action id="entityOpen" type="entity_open"/>
</actions>
</entityComboBox>
Чтобы добавить действие в Jmix Studio, выберите компонент в XML-дескрипторе экрана или в панели структуры Jmix UI и нажмите кнопку Add→Action в панели инспектора Jmix UI. |
Подробную информацию об определении пользовательских и предопределенных действий смотрите в разделе Действия для entityPicker
.
Ленивая загрузка
Компонент поддерживает загрузку элементов пакетами в ответ на ввод пользователя, а не загрузку всех элементов сразу. Это помогает обеспечить удобство работы пользователя даже при работе с большим количеством элементов.
Декларативная конфигурация
Чтобы реализовать ленивую загрузку в дескрипторе экрана, вместо указания атрибута itemsContainer
, настройте вложенный элемент itemsQuery
. Например, чтобы загружать не более 30 элементов и отображать их в списке, сделайте следующее:
<entityComboBox metaClass="Department" pageSize="30"> (1)
<itemsQuery class="com.company.onboarding.entity.User"
searchStringFormat="(?i)%${inputString}%"
escapeValueForLike="true"
fetchPlan="_instance_name"> (2)
<query>
<![CDATA[select e from Department e where e.name like :searchString order by e.name]]> (3)
</query>
</itemsQuery>
</entityComboBox>
1 | Атрибут pageSize определяет размер пакета при загрузке данных из базы данных. По умолчанию он равен 50. |
2 | Атрибуты в itemsQuery обеспечивают контроль над процессом получения данных. Они следующие:
|
3 | Запрос JPQL. |
Программная конфигурация
Получение элементов также можно определить программно, используя обработчик itemsFetchCallback
. Например:
<entityComboBox id="departmentComboBox" metaClass="Department"/>
@ViewComponent
private EntityComboBox<Department> departmentField;
@Install(to = "departmentComboBox", subject = "itemsFetchCallback")
private Stream<Department> departmentFieldItemsFetchCallback(final Query<Department, String> query) {
String param = query.getFilter().orElse("");
return dataManager.load(Department.class)
.condition(PropertyCondition.contains("name", param).skipNullOrEmpty())
.firstResult(query.getOffset())
.maxResults(query.getLimit())
.list()
.stream();
}
В этом примере данные извлекаются с использованием DataManager, но вы можете использовать этот подход для загрузки из пользовательского сервиса.
Пользовательский рендерер
По умолчанию экземпляры, отображаемые в выпадающем списке, обычно отображаются как простой текст. Пользовательский рендерер позволяет задать собственную логику отображения для каждого элемента, включая различные компоненты, значки или даже контейнеры.
Например, определим следующий рендерер, чтобы добавить значок перед названием отдела:
@Supply(to = "customRendererField", subject = "renderer")
private Renderer<Department> departmentRenderer() {
return new ComponentRenderer<>(department -> {
Icon icon = VaadinIcon.USERS.create();
HorizontalLayout contentBox = uiComponents.create(HorizontalLayout.class);
contentBox.setPadding(false);
contentBox.add(icon);
contentBox.add(department.getName());
return contentBox;
});
}
В качестве альтернативы вы можете отображать элементы, используя вложенный элемент fragmentRenderer
. Обратитесь к разделу Рендерер фрагментов для получения дополнительной информации.
Атрибуты
id - alignSelf - allowCustomValue - ariaLabel - ariaLabelledBy - allowedCharPattern - autoOpen - autofocus - classNames - colspan - css - dataContainer - enabled - errorMessage - focusShortcut - height - helperText - itemsContainer - label - maxHeight - maxWidth - metaClass - minHeight - minWidth - opened - overlayClass - pageSize - pattern - placeholder - property - readOnly - required - requiredMessage - tabIndex - themeNames - title - visible - width
allowCustomValue
Если атрибут allowCustomValue
имеет значение true
, пользователь может вводить строковые значения, которые не соответствуют ни одной существующей метке элемента, что вызовет событие CustomValueSetEvent.
Обратите внимание, что entityComboBox
не выполняет никаких действий со строковым пользовательским значением автоматически. Используйте CustomValueSetEvent
, чтобы определить, как следует обрабатывать пользовательское значение.
По умолчанию установлено значение false
.
itemsContainer
Устанавливает имя контейнера данных, который содержит список элементов. Компонент будет отображать имя экземпляра сущности.
Обработчики
AttachEvent - BlurEvent - ComponentValueChangeEvent - CustomValueSetEvent - DetachEvent - FocusEvent - itemLabelGenerator - statusChangeHandler - validator - renderer
Чтобы сгенерировать заглушку обработчика в Jmix Studio, используйте вкладку Handlers панели инспектора Jmix UI, или команду Generate Handler, доступную на верхней панели контроллера экрана и через меню Code → Generate (Alt+Insert / Cmd+N). |
CustomValueSetEvent
com.vaadin.flow.component.combobox.ComboBoxBase.CustomValueSetEvent
возникает, когда пользователь вводит непустое значение, которое не соответствует ни одному из существующих элементов. Чтобы разрешить ввод пользовательских значений, установите атрибуту allowCustomValue значение true
.
<entityComboBox dataContainer="userDc"
property="department"
itemsContainer="departmentsDc"
id="departmentField"
allowCustomValue="true"/>
@ViewComponent
private CollectionContainer<Department> departmentsDc;
@ViewComponent
private EntityComboBox<Department> departmentField;
@Autowired
private DataManager dataManager;
@Subscribe("departmentField")
public void onDepartmentFieldCustomValueSet(ComboBoxBase.CustomValueSetEvent
<ComboBox<Department>> event) {
Department department = dataManager.create(Department.class); (1)
department.setName(event.getDetail()); (2)
departmentsDc.getMutableItems().add(department); (3)
departmentField.setValue(department);
}
1 | Создайте новый экземпляр и объедините его с контекстом. |
2 | Установите имя для вновь созданной сущности department . |
3 | Добавьте объединенную сущность. |
Элементы
actions - fragmentRenderer - itemsQuery - prefix - tooltip - validator