寻址其他命名容器中的组件

时间:2011-11-16 13:32:41

标签: jsf-2 facelets myfaces composite-component

我想要实现的是能够从其他命名容器中解决一些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;来自复合组件中的消息?

1 个答案:

答案 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>即可解决其他问题。