Рендереры
Эта страница описывает общие API рендереров, такие как ComponentRenderer, LitRenderer и FragmentRenderer, которые используются в UI-компонентах. Предопределенные XML-рендереры, поддерживаемые атрибуты и примеры для конкретных компонентов смотрите в соответствующей документации.
Рендереры особенно полезны для:
-
Улучшенного визуального представления: Они позволяют включать визуальные элементы помимо простого текста, такие как иконки, изображения, индикаторы выполнения и другие, чтобы сделать данные более понятными и привлекательными. Это может улучшить общий пользовательский опыт и ясность интерфейса.
-
Условное отображение: Рендереры могут реализовывать логику, изменяющую визуальное представление в зависимости от значения данных или другой контекстной информации. Например, рендерер может отображать зеленую галочку для успешных записей и красный крестик для неудачных.
-
Сложные макеты: В случаях, требующих более сложных визуальных макетов, чем предлагает стандартное отображение, пользовательские рендереры обеспечивают гибкость в организации и отображении данных нестандартными способами. Это может включать в себя комбинирование нескольких элементов UI в одной ячейке компонента или создание полностью пользовательских макетов.
| Если нужно только изменить способ отображения значения, например даты или числа, используйте форматтер. |
Рендерер компонентов
ComponentRenderer отображает элементы с помощью UI-компонентов, а не обычного текста. Его можно задать программно с помощью setRenderer() или предоставить из контроллера через @Supply.
ComponentRenderer создает UI-компоненты для отображаемых элементов и может влиять на производительность при работе с большими наборами данных. Если вам нужно только отобразить HTML-подобный контент, используйте LitRenderer.
|
ComponentRenderer можно создавать разными способами, в зависимости от того, как вы хотите создавать и обновлять компоненты. Ниже показаны доступные варианты.
Один обработчик
Используйте этот вариант, когда одна функция может сразу создать новый экземпляр компонента на основе текущего элемента.
@Supply(to = "selectWithRenderer", subject = "renderer") (1)
private ComponentRenderer<Button, Department> selectWithRendererRenderer() {
return new ComponentRenderer<>(item -> { (2)
Button button = uiComponents.create(Button.class); (3)
button.setText(item.getName());
button.setIcon(VaadinIcon.DESKTOP.create());
return button; (4)
});
}
| 1 | @Supply привязывает рендерер к selectWithRenderer. |
| 2 | Функция получает текущий элемент. |
| 3 | Экземпляр компонента создается и настраивается в этом же обработчике. |
| 4 | Функция возвращает компонент для текущего элемента. |
Раздельные создание и привязка
Используйте этот вариант, когда создание компонента и привязку данных к нему нужно разделить.
@Supply(to = "dataGridCheckbox.active", subject = "renderer") (1)
private Renderer<User> dataGridCheckboxActiveRenderer() {
return new ComponentRenderer<>(
() -> {
JmixCheckbox checkbox = uiComponents.create(JmixCheckbox.class); (2)
checkbox.setReadOnly(true); (3)
return checkbox; (4)
},
(checkbox, item) -> checkbox.setValue(item.getActive()) (5)
);
}
| 1 | @Supply привязывает рендерер к колонке active компонента dataGridCheckbox. |
| 2 | Поставщик создает экземпляр компонента JmixCheckbox. |
| 3 | Чекбокс переводится в режим "только для чтения". |
| 4 | Поставщик возвращает экземпляр компонента. |
| 5 | Consumer получает компонент и текущий элемент, затем устанавливает значение флажка из item.getActive(). |
Явное обновление
Используйте этот вариант, когда обновление элемента требует большего контроля, чем в предыдущих примерах. При обновлении можно переиспользовать текущий экземпляр компонента или заменить его новым.
@Supply(to = "dataGridStatus.status", subject = "renderer")
private Renderer<User> createUpdatableStatusRenderer() {
return new ComponentRenderer<>(
item -> {
Span span = uiComponents.create(Span.class); (1)
updateSpanBadge(span, item); (2)
return span; (3)
},
(component, item) -> {
if (item.getOnboardingStatus() == null) { (4)
updateUnknownStatus(component); (5)
return component; (6)
} else {
return createStatusBadge(item); (7)
}
}
);
}
| 1 | Коллбэк создания создает начальный экземпляр Span. |
| 2 | Начальный компонент заполняется значением текущего элемента и оформляется как badge. |
| 3 | Коллбэк создания возвращает компонент. |
| 4 | Коллбэк обновления проверяет, есть ли у текущего элемента значение статуса. |
| 5 | Если значение отсутствует, коллбэк обновляет текущий экземпляр компонента. |
| 6 | Текущий компонент возвращается без замены. |
| 7 | Если значение присутствует, коллбэк создает и возвращает новый компонент для этого элемента. |
Дополнительные примеры ComponentRenderer доступны в документации компонентов, которые его поддерживают:
LitRenderer
LitRenderer выполняет рендеринг контента с использованием HTML и синтаксиса привязки данных Lit; он более легковесный, чем компонентные рендереры.
LitRenderer позволяет определять HTML-шаблон и связывать свойства сущности с переменными шаблона.
@Supply(to = "dataGridLit.userInfo", subject = "renderer")
private Renderer<User> dataGridLitUserInfoRenderer() {
return LitRenderer.<User>of("${item.firstName}<br>${item.lastName}<br>${item.email}")
.withProperty("firstName", User::getFirstName)
.withProperty("lastName", User::getLastName)
.withProperty("email", User::getEmail);
}
LitRenderer выполняет рендеринг эффективно и идеально подходит для высокопроизводительных приложений, требующих частых обновлений. Его легковесность делает его подходящим для приложений со множеством компонентов или динамическим контентом.
|
LitRenderer можно использовать в следующих компонентах пользовательского интерфейса:
Рендерер фрагментов
Рендереры для virtualList, dataGrid и других компонентов могут быть определены с помощью фрагментов. Специальный XML-элемент fragmentRenderer используется для декларативного описания рендерера.
Как и обычные фрагменты, fragmentRenderer определяется с помощью дескриптора и контроллера Java.
-
Создайте XML-дескриптор FragmentRenderer
Дескриптор может содержать необязательный instanceContainer для сущности, которая будет использоваться рендерером.
<fragment xmlns="http://jmix.io/schema/flowui/fragment"> <data> <instance id="userDc" class="com.company.onboarding.entity.User"> <loader id="userDl"/> <fetchPlan extends="_base"/> </instance> </data> <content> <hbox> <icon icon="ANGLE_DOUBLE_RIGHT"/> <formLayout id="form" dataContainer="userDc"> <textField property="username" readOnly="true"/> <textField property="firstName" readOnly="true"/> <textField property="lastName" readOnly="true"/> <textField property="email" readOnly="true"/> </formLayout> </hbox> </content> </fragment>Если instanceContainerне определен, вы можете использовать методFragmentRenderer.getItem()для обработки рендеринга. -
Создайте FragmentRenderer Java-контроллер
Класс рендерера фрагмента должен расширять базовый класс
FragmentRendererс параметрами типа, указывающими корневой компонент и отображаемую сущность, например:@FragmentDescriptor("user-fragment.xml") (1) @RendererItemContainer("userDc") (2) public class UserFragment extends FragmentRenderer<HorizontalLayout, User> { }1 Аннотация @FragmentDescriptorзадает строковое значение - путь к XML-файлу, используемому для инициализации фрагмента.2 Аннотация @RendererItemContainerиспользуется для указания контейнера данных, принимающего отображаемую сущность. -
Используйте FragmentRenderer в экране
Выберите компонент, в котором вы хотите отобразить элементы, и добавьте элемент
fragmentRenderer. Этот элемент требует атрибутclass, указывающий полное имя класса (FQN), расширяющего абстрактный классio.jmix.flowui.fragmentrenderer.FragmentRenderer.<virtualList itemsContainer="usersDc"> <fragmentRenderer class="com.company.onboarding.view.component.virtuallist.UserFragment"/> </virtualList>Чтобы добавить
fragmentRendererв Jmix Studio, выберите UI-компонент в XML-дескрипторе экрана или на панели структуры Jmix UI и нажмите кнопку Add→FragmentRenderer на панели инспектора Jmix UI.Элемент
fragmentRendererтакже поддерживает загрузку свойств, так же как и элементfragment.
Вы можете использовать fragmentRenderer в следующих UI-компонентах: