何时使用 <ui:include>、标记文件、复合组件和/或自定义组件? [英] When to use <ui:include>, tag files, composite components and/or custom components?

查看:14
本文介绍了何时使用 <ui:include>、标记文件、复合组件和/或自定义组件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开始将 JSF 2.0 与 Facelets 一起使用,并且对新的复合组件感到困惑,因为我知道现有的 和 Facelets 1.x 提供的其他模板技术.

I started using JSF 2.0 with Facelets recently and got puzzled by new composite components knowing existing <ui:include> and other templating techniques offered by Facelets 1.x.

这些方法有什么区别?从功能上讲,它们似乎提供了相同的内容:+ vs 标签文件,重用现有模板.在复合组件的情况下,除了语法和清晰的接口规范之外还有什么吗?性能会有所不同吗?

What is the difference between those approaches? Functionally they seem to offer about the same: <ui:param> vs <cc:attribute>, <ui:insert>+<ui:define> vs tag files, reuse of the existing templates. Is there anything besides syntax and clear interface specification in case of composite components? Could performance differ?

推荐答案

这些方法有什么区别?

Facelet 模板

使用 Facelet 模板(如 ) 如果要将主页布局片段拆分为可重复使用的模板.例如.页眉、菜单、内容、页脚等

Facelet templates

Use Facelet templates (as in <ui:composition>, <ui:include> and <ui:decorate>) if you want to split main page layout fragments into reuseable templates. E.g. header, menu, content, footer, etc.

示例:

如果您想拥有一组可重复使用的组件以防止/最小化代码重复,请使用 Facelet 标记文件.例如.一组标签+输入+消息组件.与复合组件的主要区别在于,Facelet 标记文件的输出不代表单个 UIComponent,并且在某些情况下可能是复合组件不够用的唯一解决方案.通常,具有一个 和一个或多个 传递托管 bean 属性(因此不是硬编码值)是一个表明包含文件最好是标记文件.

Use Facelet tag files if you want to have a reuseable group of components in order to prevent/minimize code duplication. E.g. a group of label+input+message components. The major difference with composite components is that the output of a Facelet tag file does not represent a single UIComponent and may in some circumstances be the only solution when a composite component doesn't suffice. Generally, having an <ui:include> with one or more <ui:param> which passes a managed bean property (and thus not a hardcoded value) is a signal that the include file can better be a tag file.

示例:

如果您想使用纯 XML 创建具有单一职责的单一且可重用的自定义 UIComponent,请使用复合组件.这样的复合组件通常由一堆现有组件和/或 HTML 组成,并且在物理上呈现为单个组件,并且应该绑定到单个 bean 属性.例如.由 3 个依赖 组件表示单个 java.time.LocalDate 属性的组件,表示日、月和年,或组合了 的组件><p:fileUpload><p:imageCropper> 合并成一个 引用一个自定义的 com.example.Image 实体作为属性.

Use composite components if you want to create a single and reuseable custom UIComponent with a single responsibility using pure XML. Such a composite component usually consists of a bunch of existing components and/or HTML and get physically rendered as single component and is supposed to be bound to a single bean property. E.g. a component which represents a single java.time.LocalDate property by 3 dependent <h:selectOneMenu> components representing day, month and year, or a component which combines <p:fileUpload> and <p:imageCropper> into a single <my:uploadAndCropImage> referring a single custom com.example.Image entity as property.

示例:

当由于缺乏标准/可用组件集的支持而无法使用 Facelet 标记文件或复合组件实现功能时,请使用自定义组件.通常,当您想要对解码和/或编码进行高度控制和/或定制,并且还为最终用户提供相对容易地扩展/覆盖解码和/或编码的可能性时.示例可以在开源组件库的源代码中找到,例如 PrimeFacesOmniFaces.

Use a custom component whenever the functionality cannot be achieved with Facelet tag files or composite components, because of the lack of support in the standard/available set of components. Generally when you want a high degree of control and/or customization of the decoding and/or encoding, and also to offer the endusers the possibility to relatively easily extend/override the decoding and/or encoding. Examples can be found over all place in source code of open source component libraries such as PrimeFaces and OmniFaces.

当您想要控制 JSF 组件树的构建而不是 HTML 输出的呈现时,您应该使用标记处理程序而不是组件.

When you want to control the building of the JSF component tree instead of rendering of the HTML output, then you should use a tag handler instead of a component.

示例:

以下是一些利用上述所有技术的示例项目.

Here are some example projects which utilize all of above mentioned techniques.

  • Java EE Kickoff App (templates - includes - tagfiles - composite)
  • OmniFaces Showcase (templates - includes - tagfiles - composite)

性能会有所不同吗?

从技术上讲,性能问题可以忽略不计.应根据具体的功能需求和实现的最终抽象程度、可重用性和可维护性来进行选择.每种方法都有其明确的目的和局限性.

Technically, the performance concern is negligible. The choice should be made based on the concrete functional requirements and the final degree of abstraction, reusability and maintainability of the implementation. Each approach has its own well definied purpose and limitations.

然而,在构建/恢复视图期间(特别是:在保存/恢复视图状态期间),复合组件确实有很大的开销.而且,在旧版本的 Mojarra 中,复合组件在分配默认值时存在性能问题,自 2.1.13 以来已经修复.此外,当 <cc:attribute method-signature> 用于方法表达式,基本上整个组件树都会在 HTTP 会话中重新引用,这是自 2.1.29/2.2.8 以来修复的.在旧的 2.1 版本中可以绕过内存泄漏,如下所示:

Composite components do however have a significant overhead during building/restoring of the view (specifically: during saving/restoring the view state). And, in older versions of Mojarra, composite components had performance issues with assigning default values, this is already fixed since 2.1.13. Also, Mojarra had a memory leak when a <cc:attribute method-signature> is used for method expressions, basically the entire component tree is re-referenced in HTTP session, this is fixed since 2.1.29 / 2.2.8. The memory leak can be bypassed in older 2.1 versions as below:

<context-param>
    <param-name>com.sun.faces.serializeServerState</param-name>
    <param-value>true</param-value>
</context-param>

或者在旧的 2.2 版本中,如下所示:

Or in older 2.2 versions as below:

<context-param>
    <param-name>javax.faces.SERIALIZE_SERVER_STATE</param-name>
    <param-value>true</param-value>
</context-param>

不过,当你有相对很多"的时候复合组件,并且您将 javax.faces.STATE_SAVING_METHOD 设置为 client,那么性能将很痛苦.如果您只想使用简单的包含文件或标记文件已经可以实现的基本功能,请不要滥用复合组件.不要使用易于配置(阅读:不需要 *.taglib.xml 文件)作为选择复合组件而不是标记文件的借口.

Still, when you have relatively "a lot of" composite components, and you have javax.faces.STATE_SAVING_METHOD set to client, then the performance will be a pain. Do not abuse composite components if you merely want the basic functionality which is already possible with a simple include file or tag file. Do not use the ease of configuration (read: no *.taglib.xml file needed) as an excuse to prefer composite components over tag files.

使用 Mojarra 2.2.10 或更早版本时,不要忘记禁用生产模式下相对较短的 Facelets 刷新周期:

When using Mojarra 2.2.10 or older, do not forget to disable the relatively short Facelets refresh period for production mode:

<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.

Do not use this setting for development, otherwise you've to restart the whole server to get changes in Facelets files to be reflected! Mojarra 2.2.11 and newer, and MyFaces already defaults to -1 when javax.faces.PROJECT_STAGE is not set to Development.

这篇关于何时使用 &lt;ui:include&gt;、标记文件、复合组件和/或自定义组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆