1

こんにちは、選択属性を実装する類似の CC を実装したいと考えています。これは、Primeface のインスタント行選択 に似てい<p:dataTable selection="#{bean.user}" .../>ます。

これは、コンポジット内の関連する定義です。

<composite:interface componentType="my.CcSelection">
  <composite:attribute name="actionListener" required="true"
          method-signature="void listener(javax.faces.event.AjaxBehaviorEvent)"/>
  <composite:attribute name="selection"/>
</composite:interface>

<composite:implementation>
  ...
  <ui:repeat var="item" value="#{cc.attrs.data}">
    <p:commandLink actionListener="#{cc.actionListener(item)}"/>
  </ui:repeat>
  ...
</composite:implementation>

バッキング BeanのactionListener-method は次のとおりです。

public void actionListener(MyObject object)
{
  logger.info("ActionListener "+object); //Always the correct object
  FacesContext context = FacesContext.getCurrentInstance();

  Iterator<String> it = this.getAttributes().keySet().iterator();
  while(it.hasNext()) {   //Only for debugging ...
    logger.debug(it.next());
  }

  // I want the set the value here
  ValueExpression veSelection = (ValueExpression)getAttributes().get("selection");
  veSelection.setValue(context.getELContext(), object);

  // And then call a method in a `@ManagedBean` (this works fine)  
  MethodExpression al = (MethodExpression) getAttributes().get("actionListener");
  al.invoke(context.getELContext(), new Object[] {});
}

CC を選択用の値式で使用すると(例: selection="#{testBean.user}"is veSelection(nullおよび選択はデバッグ反復で出力されない)、NPE を取得します。文字列を渡すと (例:selection="test"属性選択はデバッグで使用可能です) -繰り返し、しかし(もちろん)私は得るClassCastException

java.lang.String cannot be cast to javax.el.ValueExpression

コンポーネントにactionListenerselection属性を提供し、最初のステップで選択した値を設定してからactionListenerを呼び出すにはどうすればよいですか?

4

1 に答える 1

2

デバッグの繰り返しに関しては、 のキーセットにもエントリーセットにも値式は表示されませんUIComponent#getAttributes()。これはjavadocでも明示的に言及されています。つまり、そのマップには、静的な値を持つエントリのみが含まれます。マップ上で明示的に呼び出しget()、基になる属性が値式である場合にのみ、実際に呼び出して評価された値を返します。

値式を取得するには、UIComponent#getValueExpression()代わりに使用します。

ValueExpression selection = getValueExpression("selection");

メソッド式に関しては、コンポジットがから拡張されている場合はそれが最も簡単ですUICommandが、これはあなたの特定のケースでは単純に不器用です。リスナー メソッドのターゲットをコマンド リンク<f:setPropertyActionListener>に設定し、Bean で必要なプロパティを設定するために使用するだけです。この方法では、バッキング コンポーネントは不要です。

<composite:interface>
  <composite:attribute name="actionListener" required="true" targets="link"
          method-signature="void listener(javax.faces.event.AjaxBehaviorEvent)"/>
  <composite:attribute name="selection"/>
</composite:interface>

<composite:implementation>
  ...
  <ui:repeat var="item" value="#{cc.attrs.data}">
    <p:commandLink id="link">
      <f:setPropertyActionListener target="#{cc.attrs.selection}" value="#{item}" />
    </p:commandLink>
  </ui:repeat>
  ...
</composite:implementation>
于 2013-01-27T18:55:51.840 に答える