2012-01-27 11 views
4

ここでは非常に簡単なシナリオを示しています。しかし、複合コンポーネントとf:属性タグには何とか詰まっています。コードをできるだけシンプルに保つようにします。複合コンポーネント内でのf:属性の使用

複合コンポーネント:

<cc:interface name="button"> 
    ... 
    <cc:attribute 
     name="actionListener" 
     required="true" 
     method-signature="void f(javax.faces.event.ActionEvent)" 
     target="button" 
     shortDescription="The action listener for this button." /> 
    ... 
</cc:interface> 

<cc:implementation> 
    <ice:commandButton 
     ... 
     actionListener="#{cc.attrs.actionListener}" 
     ...> 

     <cc:insertChildren /> 
    </ice:commandButton> 
</cc:implementation> 

...今、私たちは次のようにコンポーネントを使用します。

<ctrl:button 
    ... 
    actionListener="#{bean.method}" 
    ...> 
    <f:attribute name="objectId" value="#{someObject.id}" /> 
</ctrl:button> 

今、私たちはアクションリスナメソッド内で "OBJECTID" 属性にアクセスする必要があります。私たちはすでに次のような形式を試みました:

public void method(ActionEvent event) 
{ 
    ... 
    event.getComponent().getAttributes().get("objectId"); 
    ... 
} 

しかし、属性マップにはobjectIdが含まれていません。このアプローチに何か問題はありますか?この問題を解決するために推奨される方法は何ですか?

誰かが私たちを助けることができたらうれしいです。

ありがとうございます! SlimShady

答えて

5

この<f:attribute>ハックは、オブジェクトをコマンドボタン/リンクの追加引数として渡すことができなかったときのJSF 1.0/1.1からの残されたものです。 JSF 1.2以降、<f:setPropertyActionListener>を使用することになっています。 (サーブレット3.0の標準的な部分であるが、JBoss ELの助けを借りて、実現可能なサーブレット2.5用です)EL 2.2以降

<ctrl:button action="#{bean.method}"> 
    <f:setPropertyActionListener target="#{bean.objectId}" value="#{someObject.id}" /> 
</ctrl:button> 

あなたの代わりにしても、単にメソッドの引数として、オブジェクト全体を渡すことができます。

<ctrl:button action="#{bean.method(someObject.id)}" /> 
+0

Hey @BalusC :)私たちは現在JSF 2に移行中で、同様の問題に直面しています。私は2つの質問があります: 'f:setPropertyActionListener'はtargetを必要とし、spec TLDはタグの' name'属性をリストしません。 'target'を意味すると思いますか? – truemmer

+0

@truemmer:Copypasteの間違い、はい:私はそれを修正しました。 – BalusC

+0

2番目の質問を編集するには時間がかかりすぎました.-)次の質問は、2番目の解決策です。複合コンポーネントのインターフェイスに「action」という名前の属性を設定して、「target」を指定する必要があります。なぜJSF 2仕様でアクション・メソッドにパラメータを持たないことが必要なのでしょうか? – truemmer

3

次の設定でccに渡された属性を読み取ることができました。

<test:inner> 
    <f:attribute name="fAttribute" value="myAttributeValue" /> 
</test:inner> 

<cc:implementation> 
    <h:commandButton value="button" actionListener="#{testBean.actionListener}" > 
     <f:attribute name="innerAttribute" value="innerAttributeValue" /> 
      <cc:insertChildren /> <!-- not necessary, I hoped it would pass the outer attribute ---> 
    </h:commandButton> 
</cc:implementation> 

public void actionListener(ActionEvent event) { 
    event.getComponent().getNamingContainer().getAttributes().get("fAttribute") 
    // > myAttributeValue 
    event.getComponent().getAttributes().get("innerAttribute") 
    // > innerAttributeValue 
} 

トリックは、ボタンの名前付けコンテナ内を検索することでした。したがってCCは常にネーミングコンテナであり、内部コンポーネントで終わることを確認できます。

それはそれがintendetの方法であるかどうかはわかりませんが、命名コンテナがその子のためにそのような属性を収集していることがわかっている限り、私は確信しています。

Q:ボタンに属性を渡さないと、Mojarra/JSF内のバグとみなされますか?

+0

私は」これをハックと見なすべきかどうかはわかりませんが、私はJSF 2への移行中に一時的なステップとしてソリューションを気に入っています。IMHOでは、BalusCのソリューションの第2のアプローチを長期的にとどめるべきです。 – truemmer

+0

私は@BalusCソリューションで2 conを見ると思います: 'action =#{myBean.myMethod(myParameter)}'を 'actionListener'パラメータで使うことはできません。これは便利なこともあり、' f:setPropertyActionListener 'solution inループの中にある' ui:repeat'のように、一意のBeanプロパティで値をバインドする必要があります。 –

関連する問題