2013-03-14 7 views
6

コンポジットコンポーネントを実装していて、解決策が見つからない問題が見つかりました。JSF2.0 - オプションのメソッド式を持つコンポジットコンポーネント

ページの作成者が渡すことができる属性を指定しましたが、渡されなかった場合はコンポジットコンポーネントはメソッド属性(アクションにメソッド式)を指定できませんでしたcomposite:implementationタグ内のmethod属性を使用します。ここで

私のコードは:

<composite:interface> 
    <composite:attribute name="namePrompt" required="true"/> 
    <composite:attribute name="actionMethod" method-signature="java.lang.String action()" required="false"/> 
    <composite:attribute name="showComponent" default="false"/> 
</composite:interface> 

<composite:implementation> 
    <div> 
     <p:commandLink actionListener="#{cc.attrs.actionMethod}" 
         rendered="#{cc.attrs.showComponent}" 
         > 
      <h:outputText value="#{cc.attrs.namePrompt}"/>  
     </p:commandLink> 
    </div> 
</composite:implementation> 

それを使用して、私は "actionMethod" 属性が指定されていませんでした。このように:

<util:foo namePrompt="SomeName" showComponent="true"/> 

しかし、私はエラーメッセージを取得:

javax.faces.FacesException: Unable to resolve composite component from using page using EL expression '#{cc.attrs.actionMethod}' 

これを実行する方法はありますか?

+0

あなたはactionListener' 'にオプションの属性を渡すことができます。あなたはどのようなユースケースを使用していますが、 'actionListener'が解決されず、' commandLink'がレンダリングされたらどうなると思いますか? – partlov

+0

はいリンクコンポーネントがレンダリングされますが、リンクコンポーネントでクリックアクションが発生すると、属性actionMethodのメソッドが定義されていないという文句があります。しかしそれは私の意図ですが、時にはactionMethod属性のアクションメソッドを定義したくありません。これは可能ですか?私は「必須=偽」を置くことが問題を解決すると思った。 –

答えて

10

あなたは条件付きであなたのパラメータの定義に従った2つのp:commandLink要素を作成し、それらをレンダリングする必要があります。

<p:commandLink actionListener="#{cc.attrs.actionMethod}" rendered="#{!empty cc.getValueExpression('actionMethod') and cc.attrs.showComponent}"> 
    <h:outputText value="#{cc.attrs.namePrompt}"/> 
</p:commandLink> 
<p:commandLink rendered="#{empty cc.getValueExpression('actionMethod')}"> 
    <h:outputText value="#{cc.attrs.namePrompt}"/> 
</p:commandLink> 
+0

それはうん、うん。あなたの時間と助けてくれてありがとう。 –

3

他のソリューションは、アクションメソッドで、独自のコンポーネントタイプを作成することです。例:

<composite:interface componentType="myButton"> 
    <composite:attribute name="namePrompt" required="true"/> 
    <composite:attribute name="actionMethod" method-signature="java.lang.String action()" required="false"/> 
    <composite:attribute name="showComponent" default="false"/> 
</composite:interface> 

<composite:implementation> 
    <div> 
     <p:commandLink actionListener="#{cc.action()}" rendered="#{cc.attrs.showComponent}"> 
      <h:outputText value="#{cc.attrs.namePrompt}"/>  
     </p:commandLink> 
    </div> 
</composite:implementation> 

とのcomponentTypeが見えるように持っている:

@FacesComponent("myButton") 
public class MyButton extends UINamingContainer { 

    public MyButton() { 
    } 

    public String action() { 
     MethodExpression me = (MethodExpression) this.getAttributes().get("actionMethod"); 
     if (me != null) { 
      try { 
       Object result = me.invoke(FacesContext.getCurrentInstance().getELContext(),  null); 
       if (result instanceof String) { 
        return (String) result; 
       } 
      } catch (ValidatorException ve) { 
       throw ve; 
      } 
     } 
     return null; 
    } 
} 
1

は同じ正確なエラーを持っていたし、あまりにも私のコンポーネント上の任意のアクションメソッドを持つことが必要。

したがって、対応するFacesComponentクラスのメソッドを指すメソッドシグネチャを使用して、複合属性のデフォルトパラメータを追加しようとしました。

コンポーネント:

<composite:interface componentType="myButton"> 
    <composite:attribute name="namePrompt" required="true"/> 
    <composite:attribute name="actionMethod" method-signature="java.lang.String action()" required="false" default="#{cc.dummyAction}"/> 
    <composite:attribute name="showComponent" default="false"/> 
</composite:interface> 

<composite:implementation> 
    <div> 
     <p:commandLink action="#{cc.attrs.actionMethod}" 
         rendered="#{cc.attrs.showComponent}" 
         > 
      <h:outputText value="#{cc.attrs.namePrompt}"/>  
     </p:commandLink> 
    </div> 
</composite:implementation> 

FacesComponentクラス:

@FacesComponent("myButton") 
public class MyButton extends UINamingContainer { 

    public MyButton() { 
    } 

    public String dummyAction() { 
     return ""; 
    } 

} 
3

変更java.lang.Object上位にメソッドシグネチャの戻り値の型とデフォルト値として "ヌル" を追加します。方法がなければ

<composite:interface> 
    <composite:attribute name="namePrompt" required="true"/> 
    <composite:attribute name="actionMethod" method-signature="java.lang.Object action()" required="false" default="null"/> 
    <composite:attribute name="showComponent" default="false"/> 
</composite:interface> 

<composite:implementation> 
    <div> 
     <p:commandLink actionListener="#{cc.attrs.actionMethod}" 
         rendered="#{cc.attrs.showComponent}" 
         > 
      <h:outputText value="#{cc.attrs.namePrompt}"/>  
     </p:commandLink> 
    </div> 
</composite:implementation> 

<util:foo namePrompt="SomeName" showComponent="true"/> 

方法で:

<util:foo actionMethod="#{someBean.someMethod()}" namePrompt="SomeName" showComponent="true"/> 
関連する問題