2012-07-21 40 views
2

我有一個JSF複合組件util_primefaces:inplace_name需要一個「管理器」支持bean,當實體的「名稱」字段時執行持久性更新被編輯(使用對:就地):JSF複合組件支持bean EL表達式作爲默認的必需屬性失敗,方法未知

<cc:interface> 
    <cc:attribute name="manager" type="com.example.web.AbstractManager" required="false" default="#{blockManager}"/> 
    <cc:attribute name="element" type="com.example.entity.Element" required="true"/> 
    <cc:attribute name="elid" required="true"/> 
    <cc:attribute name="update" required="false" default="@parent"/> 
.. 
</cc:interface> 

<cc:implementation> 
.. 
<p:inplace id="#{cc.attrs.elid}" editor="true" emptyLabel="UNDEF" > 
    <p:ajax 
    event="save" 
    listener="#{cc.attrs.manager.onInplaceNameSaveEvent}" 
    process="@this #{cc.attrs.elid}-name" 
    update="#{cc.attrs.update}" 
    /> 
<h:inputText id="#{cc.attrs.elid}-name" value="#{cc.attrs.element.name}"/> 
.. 

其中例如@ViewScoped @ManagedBean圖塊管理員最終延伸的AbstractManager,它有一個監聽方法:

public void onInplaceNameSaveEvent(AjaxBehaviorEvent ae). 

[ASIDE:爲異常的原因「elid」attrib UTE這裏所描述的,它在這個問題沒有進一步的作用:Primefaces p:inplace: How to more elegantly propagate the EL expression for entity to merge]

當我調用傳遞的顯式#{圖塊管理員}(或AbstractManager的其他子類)的複合材料部件,它工作正常:

<util_primefaces:inplace_name 
element="#{tenancy}" 
elid="tenancy" 
manager="#{blockManager}" 
/> 

但是,如果我沒有在#{}圖塊管理員通過,在執行就地編輯和保存我得到一個錯誤,該方法onInplaceNameSaveEvent(AjaxBehaviorEvent)不知道:

<util_primefaces:inplace_name 
element="#{tenancy}" 
elid="tenancy" 
/> 

的錯誤是:

WARNING: Method not found: [email protected](javax.faces.event.AjaxBehaviorEvent) 
javax.el.MethodNotFoundException: Method not found: [email protected](javax.faces.event.AjaxBehaviorEvent) 
at com.sun.el.util.ReflectionUtil.getMethod(ReflectionUtil.java:155) 

問:爲什麼在複合組件屬性中使用default =「#{blockManager}」時支持bean未正確使用?

回答

5

根據the documentation for the tag cc:attributedefault的值必須評估爲java.lang.String

這就是爲什麼#{blockManager}表達式不像您期望的那樣工作,您只能爲String屬性設置默認值。

要看看會發生什麼,你可以測試一個標籤庫註冊下面的函數(like showed here):

public static String typeOf(Object o) { 
    return o == null ? null : o.getClass().toString(); 
} 

,並在這樣的複合材料部件使用它:如果

<ui:composition> 
    <cc:interface> 
     <cc:attribute name="param" type="java.lang.Integer" required="true" 
      default="1" /> 
    </cc:interface> 
    <cc:implementation> 
     <h:outputText value="#{fnc:typeOf(cc.attrs.param)}" /> 
    </cc:implementation> 
</ui:composition> 

現在,您使用組件時未指定param,如下所示:

<my:comp /> 

...它將輸出class java.lang.String,因爲它使用默認屬性的ValueExpression結果,該屬性是字符串"1"

當你指定PARAM:

<my:comp param="1" /> 

...它輸出class java.lang.Integer,因爲現在它是由強迫爲cc:attribute指定的類型所產生的價值。

+0

非常感謝。順便說一句,我嘗試了幾個相關的實驗,好奇的結果,例如,如果定義一個屬性name =「testInteger」type =「java.lang.Integer」default =「1a」(注意默認字符串中的故意字母字符) :outputText value =#{cc.attrs。testInteger}「它輸出可以作爲** 1a **(不是整數),當我調用沒有顯式testInteger的組件時,但是如果我用testInteger =」1b「調用複合組件,它會按預期的方式失敗並帶NumberFormatException – 2012-07-23 07:58:35

+0

有趣。 ..也會對我自己做一些測試!謝謝!:) – elias 2012-07-23 11:41:55

+0

用示例測試更新了答案;) – elias 2012-07-23 13:02:30

相關問題