8

JSF2.0でカスタムコンポーネントをビルドしました

タグは次のようになります。

<x:myTag id="1" name="AAA" />

対応するJavaクラス:

@FacesComponent("a.b.c.MyTag")
public class UIMyTag extends UIInput {

   private String name;
   private String id;

   public String getId() {
      return id;
   }

   public void setId(String id) {
       this.id = id;
   }


   public String getId() {
      return id;
   }

   public void setId(String id) {
       this.id = id;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   @Override
   public void encodeBegin(FacesContext context) throws IOException {
       ResponseWriter writer = context.getResponseWriter();
       logger.debug(getName()); //prints null for name="#{dummyBean.name}" 
                                //   and AAA for name="AAA"
       logger.debug(getAttributes().get("name")); // always correct value
   ...
}
   ....

}

使用する場合

<x:myTag id="1" name="AAA" />

すべてが期待どおりに機能しますが、myTag属性にELを使用すると、setName()メソッドが呼び出されることはありません。だから、

<x:myTag id="#{dummyBean.id}" name="#{dummyBean.name}" />

私は常にメソッド内のプロパティを取得nullします。デバッグした後、メソッドが呼び出されないことに気付きました。ELに関する何かが混乱しているのではないかと思いましたが(その理由はまだそれに関連していると思います)、本当に奇妙なのは、プロパティがうまく機能していることです。セッターが呼び出され、エコニングが始まると値は期待どおりです。 。nameencodeBeginsetNameid

getAttributes().get("name")メソッドから呼び出すと正しい名前の値が得られることに言及する必要がencodeBeginありますが、なぜそれがgetterとsetterで機能しないのか興味があります。

私のコンポーネントに欠けているアイデアはありますか?

4

1 に答える 1

12

この動作は予想されたものであり、仕様によるものです。値式である属性値は。で設定しUIComponent#setValueExpression()ます。つまり、実際に使用された場合、通常はビューのレンダリング時にのみ評価されることになっています。

id(および)属性には特別な扱いがあります。bindingビューのビルド時に設定される前に評価されるため、 (または)属性が動的に評価されるsetValueExpression()ときにビューのレンダリングがクラッシュするため、代わりに「通常の」セッターが呼び出されます。何らかの理由で、ビューのビルド時間中とは異なる値)。idbinding

ゲッター/セッターUIComponent#getStateHelper()をローカルプロパティではなくに委任することをお勧めします。setValueExpression()最終的には(StateHelperセッターをまったく呼び出さないことに注意してください。データが必要な場合はゲッターを呼び出すだけです)、getAttributes()また、からの値を解決しますStateHelper

public String getName() {
   return (String) getStateHelper().eval("name");
}

public void setName(String name) {
    getStateHelper().put("name", name);
}

およびメソッドは、拡張元のスーパークラスですでに定義されているため、安全に削除できることに注意してください。getId()setId()UIComponentBase

于 2012-08-08T16:13:56.330 に答える