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

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

问题描述

我最近开始将JSF 2.0与Facelets结合使用,并且对新的复合组件感到困惑,因为它们知道现有的<ui:include>和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.

这些方法之间有什么区别?在功能上,它们似乎提供了几乎相同的内容:<ui:param> vs <cc:attribute><ui:insert> + <ui:define> 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模板(如<ui:composition><ui:include><ui:decorate>).例如.页眉,菜单,内容,页脚等.

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.

示例:

  • 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,并且在某些情况下可能是复合组件不足的唯一解决方案.通常,具有包含托管bean属性(因此不是硬编码值)的一个或多个<ui:param><ui:include>表示信号包含文件可以更好地是标记文件.

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.

示例:

  • 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>组合为单个<my:uploadAndCropImage>并将单个自定义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.util.Date property by 3 dependent <h:selectOneMenu> components, 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.

示例:

  • 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

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

示例:

  • 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

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

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>时,Mojarra出现了内存泄漏.用于方法表达式,基本上整个组件树都在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文件中的更改以反映出来! Mojarra 2.2.11和更高版本,并且当javax.faces.PROJECT_STAGE未设置为Development时,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天全站免登陆