如何确保JSF taglib子组件的不同ID?

时间:2014-09-03 21:40:41

标签: jsf jsf-2 jstl facelets taglib

让我们假设我们使用以下代码定义了JSF标记库:

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://java.sun.com/jsf/html">

    <h:panelGrid columns="3">
        <h:outputLabel for="myid" value="#{label}: " />
        <h:inputText id="myid" value="#{value}" required="true" />
        <h:message for="myid" />
    </h:panelGrid> 

</ui:composition>

然后我们想以某种形式使用:

<h:form id="myForm">
    <my:nameEditor value="#{item.firstname}" label="First name" />
    <my:nameEditor value="#{item.lastname}" label="Last name" />
...
</h:form>

但是没有获得可重用的编辑器,而是抛出以下错误:

  

异常消息:组件ID myForm:myid已在视图中找到。

所以我的问题是:我们如何确保来自不同标签的子组件具有不同的ID?

PS。我的游荡: 我已经尝试将带有动态前缀的变量用于id(例如id =&#34;#{prefix} myid&#34;),但<c:set ><ui:param >(以及相应的循环)都已转为out是无用的(因为JSTL表达式在渲染之前设置 - 所以我们为两个实例获得相同的值,并且没有可以很好地仅覆盖一个标记实例的范围;并且在构建组件树之后设置JSF表达式创建ID时无法看到。

最后(灵感来自https://stackoverflow.com/a/7312979/2045440)我设法让它工作&#34;将<h:dataTable>的taglib内容用单行括起来,但我真的不相信以下是我们可以实现的最漂亮的事情:

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://java.sun.com/jsf/html">
    <h:dataTable value="">
        <h:column>
            <h:panelGrid columns="3">
                <h:outputLabel for="myid" value="#{label}: " />
                <h:inputText id="myid" value="#{value}" required="true" />
                <h:message for="myid" />
            </h:panelGrid> 
        </h:column>
    </h:dataTable>
</ui:composition>

1 个答案:

答案 0 :(得分:2)

您可以将ID设置为另一个属性。

<my:nameEditor id="firstname" value="#{item.firstname}" label="First name" />
<my:nameEditor id="lastname" value="#{item.lastname}" label="Last name" />
<h:panelGrid columns="3">
    <h:outputLabel for="#{id}" value="#{label}: " />
    <h:inputText id="#{id}" value="#{value}" required="true" />
    <h:message for="#{id}" />
</h:panelGrid> 

那应该是有用的。另一种方法是将其包装在命名容器中,如<f:subview>

<f:subview id="#{id}">
    <h:panelGrid columns="3">
        <h:outputLabel for="myid" value="#{label}: " />
        <h:inputText id="myid" value="#{value}" required="true" />
        <h:message for="myid" />
    </h:panelGrid> 
</f:subview>

另一种替代方法是将其转换为复合组件,该组件本质上已经是命名容器,但我个人建议为此目的坚持使用tagfile。

另见: