渲染器
该章节介绍 UI 组中可以使用的通用渲染器 API,例如 ComponentRenderer、LitRenderer 或 FragmentRenderer。对于预定义的 XML 渲染器,支持的属性,以及特定组件的示例,请参考对应组件的文档。
渲染器特别适合以下场景:
-
增强的可视化展示:能够包含纯文本之外的视觉元素,例如图标、图像、进度条或其他元素,使数据更容易理解和吸引人。因此可以提升整体的用户体验和 UI 所表达意思的清晰度。
-
按条件渲染:渲染器可以根据数据值或其他上下文信息更改视觉展示。例如,为成功的记录显示绿色对勾标记,为失败的记录显示红色对勾标记。
-
复杂的布局:在需要提供复杂渲染布局的情况下,自定义渲染器可以提供以非标准方式排列和显示数据的灵活性。例如可以在单个组件单元中组合多个 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 将渲染器与 dataGridCheckbox 的 active 列绑定。 |
| 2 | 这个 lambda 方法是 supplier 方法,创建一个 JmixCheckbox 组件实例。 |
| 3 | 复选框被设置为只读模式。 |
| 4 | supplier 返回组件实例。 |
| 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 | creation 回调创建初始的 Span 组件实例。 |
| 2 | 设置初始组件值并配置为当前数据的徽章样式。 |
| 3 | creation 回调返回组件。 |
| 4 | update 回调检查当前数据是否有状态值。 |
| 5 | 如果值缺失,回调更新当前组件实例。 |
| 6 | 当前组件保持不变并返回。 |
| 7 | 如果值存在,回调为该项创建并返回一个新组件。 |
可在支持 ComponentRenderer 的 UI 组件中查看更多示例:
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);
}
下列 UI 组件可以使用 LitRenderer:
Fragment 渲染器
virtualList、dataGrid 等组件的渲染器可以通过 fragments 定义。XML 中使用特定的 fragmentRenderer 元素指定渲染器。
与普通 fragment 一样,fragmentRenderer 也是通过 XML 和 Java 控制器定义。
-
创建 FragmentRenderer 的 XML
XML 中包含可选的 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>如果未定义实例数据容器,则可以用 FragmentRenderer.getItem()方法处理渲染。 -
创建 FragmentRenderer Java 控制器
Fragment 渲染器类需要继承自
FragmentRenderer,并使用泛型参数指定组件的根元素和渲染的实体,示例:@FragmentDescriptor("user-fragment.xml") (1) @RendererItemContainer("userDc") (2) public class UserFragment extends FragmentRenderer<HorizontalLayout, User> { }1 @FragmentDescriptor注解指定一个字符串值,指向 fragment 的 XML 文件路径。2 @RendererItemContainer注解用于指定所渲染实体的数据容器。 -
在视图中使用 FragmentRenderer
在需要使用 fragment 渲染的组件中添加
fragmentRenderer元素。该元素需要指定一个class属性,需配置为继承自io.jmix.flowui.fragmentrenderer.FragmentRenderer的渲染器类的全限名称。<virtualList itemsContainer="usersDc"> <fragmentRenderer class="com.company.onboarding.view.component.virtuallist.UserFragment"/> </virtualList>如需在 Jmix Studio 中添加
fragmentRenderer,请在视图 XML 或 Jmix UI 结构面板中选择 UI 组件,然后点击属性面板中的 Add→FragmentRenderer。fragmentRenderer与普通fragment一样,也支持 传参。
以下 UI 组件支持 fragmentRenderer: