我突然想到ui:decorate
在功能上与ui:include
是一样的,唯一的区别是你可以向被包含的文件传递ui:param
和ui:define
。
我是不是有些疯了?
编辑:虽然事实上你也可以向ui:include
文件传递ui:param
,但我已经在做了。也许你也可以传递一个ui:define
,我将会检查并在这里进行编辑。
<ui:include>
和<ui:decorate>
的主要区别在于,<ui:decorate>
旨在允许插入用户定义的模板组件,而<ui:include>
则旨在包含一个现有的、已经预定义的模板。
这确实意味着<ui:decorate>
支持其体中的<ui:define>
用于用户定义的模板组件,并且可以将其插入到模板中的<ui:insert>
位置。
这里是一个有点笨拙的示例,展示了它可以使用的地方:
/WEB-INF/templates/field.xhtml
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
>
<h:outputLabel for="#{id}" value="#{label}" />
<ui:insert name="input" />
<h:message id="#{id}_message" for="#{id}" />
</ui:composition>
/page.xhtml
<h:panelGrid columns="3">
<ui:decorate template="/WEB-INF/templates/field.xhtml">
<ui:param name="label" value="Foo" />
<ui:param name="id" value="foo" />
<ui:define name="input">
<h:inputText id="foo" value="#{bean.foo}" required="true" />
</ui:define>
</ui:decorate>
<ui:decorate template="/WEB-INF/templates/field.xhtml">
<ui:param name="label" value="Bar" />
<ui:param name="id" value="bar" />
<ui:define name="input">
<h:selectBooleanCheckbox id="bar" value="#{bean.bar}" required="true" />
</ui:define>
</ui:decorate>
...
</h:panelGrid>
注意它在面板网格的每个单元格中很好地呈现组件。再次强调,这个例子非常笨拙,我会使用标签文件。只有在更大的部分,例如一个整个表单,其头部或页脚应该是可自定义的时候,才适用<ui:decorate>
。
<ui:decorate>
的另一个重要优点是它允许您将模板与组合组件一起使用。也可以参见JSF 2中是否可以使用模板和组合组件?/page.xhtml
示例中,<ui:define>
是最终用户可以定义变量模板组件的位置。 - BalusC<ui:insert>
/<ui:define>
更改由 <ui:include>
包含的页面片段。 - BalusC<ui:composition>
标签会忽略标签外的任何内容。另请参考https://dev59.com/q2445IYBdhLWcg3wkLPU#4793959 和https://dev59.com/Ymkv5IYBdhLWcg3wkBoa#10504830。 - BalusC
ui:include
没有模板开销,因此如果您只需要“仅”包含,则理论上更有效率。 - BalusC<ui:param>
只是在 EL 作用域中设置一个别名,与模板没有太多关系。 - BalusC