让我们假设我们使用以下代码定义了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>
答案 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。