2011-11-16 21 views
2

我想实现的是能够从其他命名容器中解决一些JSF组件。寻址来自其他命名容器的组件

用例:使用复合组件封装某些功能 - 用于复合组件外定义的字段。

一些代码:

<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') 

我想我明白这个问题实际上字段“nameTxt”和消息“errorMsg”位于其他命名容器中。因此,我想要做的就是指定与某个共同祖先有关的“nameTxt”的路径/ ID。

经过短时间学习算法UIComponentBase:findComponent我实际上并没有看到任何其他方式来寻找交叉命名容器,而不是通过specyfing根(即“:foo:...:nameTxt”)的整个(绝对)id路径。在更改页面结构后,这既笨拙又容易出错。

因此 - 如何正确解决复合组件中消息中的字段“nameTxt”?

+0

您使用的是JSF impl/version?我无法在Mojarra 2.1.4上重现这一点(也不适用于旧版本2.0.2)。 – BalusC

+0

这是MyFaces 2.1.2。但如果我没有错,它直接来自findComponent中的解析算法,所以meaby只需要另一种方法。但它对你有用吗? - 即你可以引用其他组件,只是普通的id,没有命名容器路径? –

回答

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的。您只需从<h:message>中删除style="display:none"即可解决其他问题。

+0

解决方法:这里的“绑定”是否有意义?而且我不确定它是否适用于不是每个组件都是命名容器的路径 - 我的意思是在客户端路径上将有所有组件,并且该算法仅适用于命名容器的id。 –

+0

对于实现的差异 - 感谢提示,目前对我来说是不可能的。请只说一下它在莫哈拉岛上如何工作 - 没有任何路径(只是id),或者从一些共同的祖先开始的路径? –

+0

确实有意义,否则解决方法将无法工作。它将组件'UIComponent'(http://download.oracle.com/javaee/6/api/javax/faces/component/UIComponent.html)绑定到视图,以便您可以通过EL在其他位置引用它在我的答案的例子中,像'forField'中的视图。它基本上通过'“:”+组件。getClientId()'到组合。回复:Mojarra,就像你最初做的那样,并且直觉上可以工作:'forField =“nameTxt”'和'for =“#{cc.attrs.forField}'。 – BalusC

相关问题