2014-09-24 42 views
2

我有一個用JSF 2.0 + PrimeFaces 3.4編寫的標記庫,現在我試圖更新到JSF 2.2和PrimeFaces 4.0。 但我意識到傳遞給組件評估的屬性的值,並導致渲染錯誤的ID。#{cc.clientId}在升級到JSF 2.2後以錯誤的組合方式進行評估

enum.xhtml(複合部件)

<cc:interface> 
      <cc:attribute name="render" default="@this"/> 
      ..... 
</cc:interface> 
<cc:implementation> 
    <h:selectOneMenu ......../> 
    <p:ajax update="#{cc.attrs.render}" process="#{cc.attrs.execute}" /> 
</cc:implementation> 

用法:

<t:enum id="authenticationSource" value="#{authenticationStrategy}" ..... 
    render=":#{cc.clientId}:tabView:passwordVisibility"/> 

渲染屬性值,其:#{cc.clientId}:tabView:passwordVisibility,應該是

:j_idt1:j_idt3:j_idt5:editorDialog:j_idt39:j_idt40:tabView:passwordVisibility` 

但它被評價爲

:j_idt1:j_idt3:j_idt5:editorDialog:j_idt39:j_idt40:tabView:autheticationSource:tabView:passwordVisibility 

渲染的屬性值在複合組件中評估並導致錯誤。應該對它的使用進行評估,就像JSF 2.0中那樣。 是否有任何配置屬性或任何可以克服此錯誤的東西。

我正在使用wildfly 8.1.0-最終

+0

也許'周圍的任何元件t:enum'已經成爲一種命名容器?是否有ID爲'autheticationSource'的元素? – Smutje 2014-09-24 13:21:01

回答

4

這個組合是不正確的設計。你不應該在組合的上下文之外使用#{cc.clientId}。更一般地說,你不應該從組合外部知道組合內部的任何信息。複合材料本身應該擔心這一點。

如果您將複合組件相互嵌套,則此構造將失敗。然後#{cc}實際上將引用「當前」複合組件。也許你依賴於舊的JSF實現中的一個bug,其中#{cc}作用域在嵌套複合組件之後未被正確清除(即,它將引用最後分配的值而不是當前上下文中可用的值)。

也許你是過度使用複合組件的唯一原因只是因爲與常規tagfiles/includes相比的零配置本質的受害者。有關何時使用這個或那個的詳細信息,請登錄到When to use <ui:include>, tag files, composite components and/or custom components?至此,僅當您想要將一組密切相關的組件綁定到一個bean屬性並且因此肯定不會一個具有多個屬性的「整個」bean。

如果您絕對肯定複合材料是您的需求的正確解決方案,並且/或者您已對此複合材料進行了相應的重構以消除所提到的誤用情況,那麼有兩種可能的方法將複合材料上的客戶端行爲組件,具體取決於具體的功能要求(如果需要,您甚至可以將這兩種方法結合使用)。

  1. 如果你想讓複合AJAX渲染的成分複合,外部化<p:ajax>(或<f:ajax>)爲<cc:clientBehavior>

    <cc:interface> 
        <cc:clientBehavior name="myCustomEventName" targets="idOfTargetComponent" event="valueChange" /> 
        ... 
    </cc:interface> 
    <cc:implementation> 
        <h:selectOneMenu id="idOfTargetComponent" ...> 
         <f:selectItems ... /> 
        </h:selectOneMenu> 
    </cc:implementation> 
    

    將被用作:

    <t:enum ...> 
        <p:ajax event="myCustomEventName" update=":absoluteClientIdOfComponentOUTSIDEComposite" /> 
    </t:enum> 
    <x:someComponent id="idOfComponentOUTSIDEComposite" /> 
    
  2. 如果你想讓複合ajax渲染一個組件裏面有這個複合體,然後讓這個複合體自己完成。

    <cc:interface> 
        ... 
    </cc:interface> 
    <cc:implementation> 
        <h:selectOneMenu ...> 
         <f:selectItems ... /> 
         <p:ajax update="idOfComponentINSIDEComposite" /> 
        </h:selectOneMenu> 
        <x:someComponent id="idOfComponentINSIDEComposite" /> 
    </cc:implementation> 
    

    而且用它通常的方式:

    <t:enum ... /> 
    
+0

對我來說不是零配置。它是關於能夠定義一個接口,而不是一堆ui:params,甚至不適用於正確的方法表達式。我想念客戶端行爲,行動資源和價值持有人在facelet模板。 – 2014-10-24 14:08:36

+1

方法表達式和動作來源:這個問題是已知的,使用''。客戶端行爲:只需使用。價值持有者:應該正常工作。 – BalusC 2014-10-27 07:25:32