在同一命名容器中重用facelets组合时避免重复的id

时间:2014-02-04 12:30:57

标签: jsf jsf-2 facelets composition

我有一个<ui:composition>,其中包含一些带有显式ID的元素和一些引用这些ID进行部分处理/更新的ajax事件。我将xhtml的这个片段封装在组合中,这样我就可以在几个不同的地方使用它,而不必复制代码。但是,当我在页面中多次使用合成(<ui:include>)时,我会得到重复的id异常。似乎JSF没有将每个组合包装在它自己的命名容器中(如<ui:component>那样)。

有没有一种简单的方法将我的作品包装在自己的命名容器中? 或者,每次我想在公共命名容器中重用xhtml片段时,是否必须使用复合组件?

2 个答案:

答案 0 :(得分:29)

根据<ui:include>模板的用途,您有以下几种选择:

  1. 使用<f:subview>。它创建了另一个NamingContainer上下文(例如<h:form><h:dataTable>,以及朋友们都这样做了:

    <f:subview id="top">
        <ui:include src="/WEB-INF/includes/some.xhtml" />
    </f:subview>
    ...
    <f:subview id="bottom">
        <ui:include src="/WEB-INF/includes/some.xhtml" />
    </f:subview>
    

    some.xhtml中定义的组件最终会在其ID中分别获得top:bottom:前缀。


  2. 将其变为tagfile,需要id属性。

    <my:some id="top" />
    ...
    <my:some id="bottom" />
    

    并使用该ID作为合成中组件ID的前缀。

    <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:someComponent id="#{id}_some" />
        <h:otherComponent id="#{id}_other" />
        ...
    <ui:composition>
    

  3. 将其变为composite component。复合组件本身已经是NamingContainer,因此它们的id属性是可选的。基本上,替换

    <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"
    >
        ...
    <ui:composition>
    

    通过

    <ui:component 
        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"
        xmlns:cc="http://java.sun.com/jsf/composite"
    >
        <cc:interface>
            <!-- This is optional. -->
        </cc:interface>
        <cc:implementation>
            ...
            <h:someComponent id="some" />
            <h:otherComponent id="other" />
            ...
        </cc:implementation>
    <ui:component>
    

    这样你可以按如下方式使用它:

    <my:some id="top" />
    ...
    <my:some id="bottom" />
    

    <cc:implementation>中定义的组件最终会在其ID中分别获得top:bottom:前缀(再次注意,复合组件的id属性是可选的,JSF将否则自动生成一个。)


  4. 另见:

答案 1 :(得分:5)

当您多次包含相同的ui:composition时,ID会重复。解决方案是在ui:param中指定特定的ui:include

假设你包含mycomposition.xhtml,你可以做类似的事情:

<ui:include src="mycomposition.xhtml">
    <ui:param name="idPrefix" value="first"/>
</ui:include>

...

<ui:include src="mycomposition.xhtml">
    <ui:param name="idPrefix" value="second"/>
</ui:include>

然后在mycomposition.xhtml中你应该声明id如下(例如h:outputText):

<h:outputText id="#{idPrefix}_text" value="My Awesome Text here"/>

现在,您可以将其余部分中的ID引用为#{idPrefix}_text