我最近开始使用带有Facelets的JSF 2.0,并且知道现有的 <ui:include> 以及Facelets 1.x提供的其他模板技术的新复合组件感到困惑 .
<ui:include>
这些方法有什么区别?从功能上讲,它们似乎提供了相同的功能: <ui:param> vs <cc:attribute> , <ui:insert> <ui:define> vs标记文件,重用现有模板 . 除了复合组件的语法和清晰的接口规范之外还有什么吗?性能会有所不同?
<ui:param>
<cc:attribute>
<ui:insert>
<ui:define>
这些方法有什么区别?
如果要将主页面布局片段拆分为可重复使用的模板,请使用Facelet模板(如 <ui:composition> , <ui:include> 和 <ui:decorate> ) . 例如 . Headers ,菜单,内容,页脚等
<ui:composition>
<ui:decorate>
例子:
How to include another XHTML in XHTML using JSF 2.0 Facelets?
What is the real conceptual difference between ui:decorate and ui:include?
How to customize h:head when using ui:composition template?
How to change head elements of a page when using ui:composition
How to ajax-refresh dynamic include content by navigation menu? (JSF SPA)
如果要使用可重复使用的组件组以防止/最小化代码重复,请使用Facelet标记文件 . 例如 . 一组标签输入消息组件 . 复合组件的主要区别在于Facelet标记文件的输出不代表单个 UIComponent ,并且在某些情况下可能是复合组件不足时的唯一解决方案 . 通常,具有一个或多个 <ui:param> 的 <ui:include> 传递托管bean属性(因此不是硬编码值)是包含文件最好是标记文件的信号 .
UIComponent
How to create a custom Facelets tag?
How to make a grid of JSF composite component?
How to create a composite component for a datatable column?
Primefaces outputLabel for composite component
如果要使用纯XML创建单个且可重复使用的自定义 UIComponent ,则使用复合组件 . 这样的复合组件通常由一堆现有组件和/或HTML组成,并且物理地呈现为单个组件,并且应该绑定到单个bean属性 . 例如 . 由3个依赖 <h:selectOneMenu> 组件表示单个 java.util.Date 属性的组件,或将 <p:fileUpload> 和 <p:imageCropper> 组合成单个 com.example.Image 实体作为属性的组件 .
<h:selectOneMenu>
java.util.Date
<p:fileUpload>
<p:imageCropper>
com.example.Image
Our Composite Component wiki page
The BalusC Code: Composite Component with multiple input fields
Split java.util.Date over two h:inputText fields representing hour and minute with f:convertDateTime
Select all items in Multiple SelectManyCheckBox with dynamic ids
Extending JSF commandLink component
Avoiding duplicate ids when reusing facelets compositions in the same naming container
每当使用Facelet标记文件或复合组件无法实现功能时,请使用自定义组件,因为标准/可用组件集中缺乏支持 . 可以在开源组件库的源代码中找到示例,例如PrimeFaces和OmniFaces .
当您想要控制JSF组件树的构建而不是呈现HTML输出时,您应该使用标记处理程序而不是组件 .
Custom Facelet component in JSF
How can I access the content of something created with ui:define programmatically?
Conditional render in tagfile depending on whether the attribute is specified or not
Performing a redirect, when conversion / validation associated with query parameters fails
以下是一些利用上述所有技术的示例项目 .
Java EE Kickoff App(templates - includes - tagfiles - composite)
OmniFaces Showcase(templates - includes - tagfiles - composite)
表现会有所不同吗?
从技术上讲,性能问题可以忽略不计 . 应根据具体功能要求以及实施的最终抽象程度,可重用性和可维护性来做出选择 . 每种方法都有其明确的目的和限制 .
但是,在构建/恢复视图期间,复合组件会产生很大的开销(具体来说:在保存/恢复视图状态期间) . 而且,在旧版本的Mojarra中,复合组件在分配默认值时存在性能问题,这已经从2.1.13开始修复 . 此外,当_2597106用于方法表达式时,Mojarra有一个memory leak,基本上整个组件树在HTTP会话中被重新引用,这是从2.1.29 / 2.2.8开始修复的 . 旧版2.1版本可以绕过内存泄漏,如下所示:
<context-param> <param-name>com.sun.faces.serializeServerState</param-name> <param-value>true</param-value> </context-param>
或者在旧的2.2版本中,如下所示:
<context-param> <param-name>javax.faces.SERIALIZE_SERVER_STATE</param-name> <param-value>true</param-value> </context-param>
但是,当你有相对"a lot of"复合组件,并且 javax.faces.STATE_SAVING_METHOD 设置为 client 时,表现将是一个痛苦 . 如果您只想要使用简单的包含文件或标记文件已经可以实现的基本功能,请不要滥用复合组件 . 不要使用易于配置(阅读:不需要 *.taglib.xml 文件)作为优先考虑复合组件而不是标签文件的借口 .
javax.faces.STATE_SAVING_METHOD
client
*.taglib.xml
使用Mojarra 2.2.10或更早版本时,不要忘记禁用 生产环境 模式的相对较短的Facelets刷新周期:
<context-param> <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name> <param-value>-1</param-value> </context-param>
不要使用此设置进行开发,否则您必须重新启动整个服务器才能反映Facelets文件中的更改!当 javax.faces.PROJECT_STAGE 未设置为 Development 时,Mojarra 2.2.11和更新版本以及MyFaces默认为 -1 .
javax.faces.PROJECT_STAGE
Development
-1
1 回答
Facelet模板
如果要将主页面布局片段拆分为可重复使用的模板,请使用Facelet模板(如
<ui:composition>
,<ui:include>
和<ui:decorate>
) . 例如 . Headers ,菜单,内容,页脚等例子:
How to include another XHTML in XHTML using JSF 2.0 Facelets?
What is the real conceptual difference between ui:decorate and ui:include?
How to customize h:head when using ui:composition template?
How to change head elements of a page when using ui:composition
How to ajax-refresh dynamic include content by navigation menu? (JSF SPA)
Facelet标记文件
如果要使用可重复使用的组件组以防止/最小化代码重复,请使用Facelet标记文件 . 例如 . 一组标签输入消息组件 . 复合组件的主要区别在于Facelet标记文件的输出不代表单个
UIComponent
,并且在某些情况下可能是复合组件不足时的唯一解决方案 . 通常,具有一个或多个<ui:param>
的<ui:include>
传递托管bean属性(因此不是硬编码值)是包含文件最好是标记文件的信号 .例子:
How to create a custom Facelets tag?
How to make a grid of JSF composite component?
How to create a composite component for a datatable column?
Primefaces outputLabel for composite component
复合组件
如果要使用纯XML创建单个且可重复使用的自定义
UIComponent
,则使用复合组件 . 这样的复合组件通常由一堆现有组件和/或HTML组成,并且物理地呈现为单个组件,并且应该绑定到单个bean属性 . 例如 . 由3个依赖<h:selectOneMenu>
组件表示单个java.util.Date
属性的组件,或将<p:fileUpload>
和<p:imageCropper>
组合成单个com.example.Image
实体作为属性的组件 .例子:
Our Composite Component wiki page
The BalusC Code: Composite Component with multiple input fields
Split java.util.Date over two h:inputText fields representing hour and minute with f:convertDateTime
Select all items in Multiple SelectManyCheckBox with dynamic ids
Extending JSF commandLink component
Avoiding duplicate ids when reusing facelets compositions in the same naming container
自定义组件
每当使用Facelet标记文件或复合组件无法实现功能时,请使用自定义组件,因为标准/可用组件集中缺乏支持 . 可以在开源组件库的源代码中找到示例,例如PrimeFaces和OmniFaces .
标记处理程序
当您想要控制JSF组件树的构建而不是呈现HTML输出时,您应该使用标记处理程序而不是组件 .
例子:
Custom Facelet component in JSF
How can I access the content of something created with ui:define programmatically?
Conditional render in tagfile depending on whether the attribute is specified or not
Performing a redirect, when conversion / validation associated with query parameters fails
示例项目
以下是一些利用上述所有技术的示例项目 .
Java EE Kickoff App(templates - includes - tagfiles - composite)
OmniFaces Showcase(templates - includes - tagfiles - composite)
从技术上讲,性能问题可以忽略不计 . 应根据具体功能要求以及实施的最终抽象程度,可重用性和可维护性来做出选择 . 每种方法都有其明确的目的和限制 .
但是,在构建/恢复视图期间,复合组件会产生很大的开销(具体来说:在保存/恢复视图状态期间) . 而且,在旧版本的Mojarra中,复合组件在分配默认值时存在性能问题,这已经从2.1.13开始修复 . 此外,当_2597106用于方法表达式时,Mojarra有一个memory leak,基本上整个组件树在HTTP会话中被重新引用,这是从2.1.29 / 2.2.8开始修复的 . 旧版2.1版本可以绕过内存泄漏,如下所示:
或者在旧的2.2版本中,如下所示:
但是,当你有相对"a lot of"复合组件,并且
javax.faces.STATE_SAVING_METHOD
设置为client
时,表现将是一个痛苦 . 如果您只想要使用简单的包含文件或标记文件已经可以实现的基本功能,请不要滥用复合组件 . 不要使用易于配置(阅读:不需要*.taglib.xml
文件)作为优先考虑复合组件而不是标签文件的借口 .使用Mojarra 2.2.10或更早版本时,不要忘记禁用 生产环境 模式的相对较短的Facelets刷新周期:
不要使用此设置进行开发,否则您必须重新启动整个服务器才能反映Facelets文件中的更改!当
javax.faces.PROJECT_STAGE
未设置为Development
时,Mojarra 2.2.11和更新版本以及MyFaces默认为-1
.