运行时视图模板
运行时视图模板可以在实体元数据上声明模板,然后应用程序运行时,根据声明的模板生成标准的列表视图和详情视图,而无需在设计时手动创建。可以使用 @ListViewTemplate 和/或 @DetailViewTemplate 实体注解,框架会在应用程序启动时生成相应的视图、路由和菜单项。
该方法有助于需要快速在 UI 中操作实体(例如查找数据或引用数据),无需为每个实体编写视图类和 XML。生成的视图与常规视图一样在系统中注册:参与 视图推断,可以通过 id 或路由打开,并且可以作为实体的主列表视图和详情视图。
| 运行时视图模板目前处于实验状态。API 和内置模板在下一个 Jmix 版本中可能会有重大变更。 |
开始使用
如需为实体生成列表视图和详情视图,需要使用注解:
@ListViewTemplate(parentMenu = "application")
@DetailViewTemplate
@JmixEntity
@Entity
@Table(name = "PRODUCT")
public class Product {
有了这两个注解,框架会在启动时生成:
-
一个 id 为
Product.list的列表视图,显示实体的 dataGrid、一个 genericFilter、分页以及 Create、Edit、Remove 操作; -
一个 id 为
Product.detail的详情视图,显示实体可编辑字段的 formLayout; -
application菜单下打开列表视图的菜单项。
这些视图使用 内置模板,内置模板根据实体属性决定渲染内容。不会在项目中创建静态 XML 或视图类。
@ListViewTemplate
@ListViewTemplate 为实体声明生成的列表视图:
@ListViewTemplate(
path = "io/jmix/flowui/view/template/list-view.ftl",
viewId = "Supplier.list",
viewRoute = "suppliers",
viewTitle = "Suppliers",
parentMenu = "application",
templateParams = """
{
"includeProperties": ["createdBy", "createdDate"],
"excludeProperties": ["internalNote"]
}
"""
)
除了 通用属性 之外,还支持:
-
lookupComponentId– 用作 查找组件 的组件 id。默认为dataGrid。
@DetailViewTemplate
@DetailViewTemplate 为实体声明生成的详情视图:
@DetailViewTemplate(
viewId = "Supplier.detail",
viewRoute = "suppliers",
viewTitle = "Supplier",
editedEntityContainerId = "entityDc"
)
除了 通用属性 之外,还支持:
-
editedEntityContainerId– 包含被编辑实体的数据容器 id,请参见 @EditedEntityContainer。默认为entityDc。
通用属性
两个注解具有以下相同属性:
| 属性 | 描述 |
|---|---|
|
指向 Freemarker XML 描述符模板的资源路径。如果省略,则使用对应的 内置模板。 |
|
传递给模板的附加参数的 JSON 对象。关于内置模板支持的参数,请参见 内置模板。 |
|
生成菜单项的父菜单项 id。如果为空,则不创建菜单项。如果指向不存在的菜单项,则会自动创建新的根菜单项。 |
|
生成视图的 id。 |
|
生成视图的路由路径。 |
|
生成视图的页面标题。 |
内置模板
当未指定 path 时,框架使用内置模板,从实体属性生成视图内容:
-
列表视图模板渲染一个
dataGrid,每个属性一列,外加genericFilter、分页和列表操作; -
详情视图模板渲染一个
formLayout,每个属性一个字段。
内置模板位于:
-
io/jmix/flowui/view/template/list-view.ftl -
io/jmix/flowui/view/template/detail-view.ftl
属性过滤
默认情况下,内置模板包含实体第一级的单值属性,并排除:
-
系统属性;
-
注解为
Secret的属性; -
id、version 和生成的属性;
-
审计和软删除属性。
内置属性过滤仅支持第一级的单值数据类型、枚举、关联和组合属性。不支持集合值数据类型属性、嵌入式属性或点号路径属性,例如 customer.name。
可以使用 templateParams 中的两个键值调整需要显示的属性集合:
-
includeProperties– 恢复被排除但能支持的第一级属性; -
excludeProperties– 移除属性;最后处理,优先级高于includeProperties。
在 Supplier 示例中,createdBy 和 createdDate 审计属性被恢复,而 internalNote 被排除:
@ListViewTemplate(
path = "io/jmix/flowui/view/template/list-view.ftl",
viewId = "Supplier.list",
viewRoute = "suppliers",
viewTitle = "Suppliers",
parentMenu = "application",
templateParams = """
{
"includeProperties": ["createdBy", "createdDate"],
"excludeProperties": ["internalNote"]
}
"""
)
组合集合(Composition Collections)
如果 @DetailViewTemplate 中使用的实体具有组合 *-to-many 属性,则生成的详情视图会渲染一个 tabSheet:
-
第一个 General 标签页包含单值字段的表单;
-
每个组合集合有自己的标签页,带有一个
dataGrid,提供 Create、Edit 和 Remove 操作。
Create 和 Edit 操作会在对话框中打开子实体自身的详情视图,因此子实体也应当带有 @DetailViewTemplate。组合集合的反向属性(子级对父级的引用)在默认情况下会在主表的列和子实体的详情表单中排除。可以使用 includeProperties 恢复。
下面的示例定义了一个带有组合集合的主实体和对应的子实体:
@ListViewTemplate(parentMenu = "application")
@DetailViewTemplate
@JmixEntity
@Entity
@Table(name = "INVOICE")
public class Invoice {
@Composition
@OneToMany(mappedBy = "invoice")
private List<InvoiceItem> items;
@DetailViewTemplate
@JmixEntity
@Entity
@Table(name = "INVOICE_ITEM")
public class InvoiceItem {
仅支持组合集合。不支持关联集合、元素集合和嵌入式属性。
没有组合集合的实体渲染为 formLayout。
自定义模板
如需完全控制生成的视图内容,可以在 path 属性中提供自定义的 Freemarker 模板。模板是位于类路径上中的 .ftl 文件,用于生成标准的视图 XML。
模板模型中可以使用以下变量:
-
entityMetaClass– 实体的MetaClass; -
viewTitle– 解析后的视图标题; -
templateHelper– 返回过滤后属性(getProperties)和组合集合属性(getCollectionProperties)的辅助对象; -
componentXmlFactory– 为属性生成编辑组件 XML 片段的工厂; -
templateParams中的所有参数,包括includeProperties和excludeProperties。
可以复制 内置模板 作为自定义模板的初始模板。
菜单集成
如果 @ListViewTemplate 或 @DetailViewTemplate 的 parentMenu 属性已设置,则在加载标准的 XML 菜单定义后,会将生成视图的菜单项追加到指定的父菜单下。如果 parentMenu 为空,则不创建菜单项。如果指向不存在的菜单项,则会自动创建新的根菜单项。