2011-11-16 40 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