我想要实现的是能够从其他命名容器中解决一些JSF组件。
Usecase:复合组件,它使用 - 封装一些特征 - 用于从复合组件定义的字段。
一些代码:
<form id="foo">
...
<label for="nameTxt">Name:</label>
<component:customError forField="nameTxt" />
<h:inputText id="nameTxt" />
...
</form>
和组件:
<composite:implementation>
<h:panelGroup id="errorComponent">
...
<h:message for="#{cc.attrs.forField}" id="errorMsg" style="display:none;" />
...
</h:panelGroup>
</composite:implementation>
问题是在渲染消息时我得到了:
Could not render Message. Unable to find component 'nameTxt' (calling findComponent on component 'j_id963445801_469fc056:errorMsg')
我想我明白问题在于这个领域&#34; nameTxt&#34;和消息&#34; errorMsg&#34;躺在其他命名容器中。所以我想要做的就是指定&#34; nameTxt&#34;的路径/ ID。与一些共同的祖先有关。
很快就研究了算法UIComponentBase:findComponent我实际上并没有看到任何其他方式来解决交叉命名容器,而是通过从根目录中指定整个(绝对)id路径(即&#34;:foo:。 ..:nameTxt&#34)。在更改页面结构后,这既笨拙又容易出错。
那么 - 如何正确地解决这个领域&#34; nameTxt&#34;来自复合组件中的消息?
答案 0 :(得分:1)
我可以在MyFaces 2.1.3上重现您的问题,但不能在Mojarra 2.1.4上重现您的问题(也不能在较旧的Mojarra 2.0.2上重现)。这可能是MyFaces中的一个错误,您需要将其报告给MyFaces guys。同时,除了(暂时)替换Mojarra的JSF实现之外,我没有看到任何其他选项。然而,它也有自己的问题,主要是它的<ui:repeat>
和部分状态保存实现。
更新:我找到了一个解决方法,但它有点笨拙:
<component:customError forField=":#{nameTxt.clientId}" />
<h:inputText id="nameTxt" binding="#{nameTxt}" />
这将使用绝对客户端ID而不是相对客户端ID进行查找。您只需要从style="display:none"
中移除<h:message>
即可解决其他问题。