2012-08-08 3 views
8

属性セッターをトリガしません。 :私が使用している場合JSF 2カスタムコンポーネントは、私は、タグは次のようになり</p> <p>JSF 2.0でカスタムコンポーネントを構築してい

@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" /> 

すべてが正常に動作しますが、ELをmyTag属性に使用すると、setName()メソッドが呼び出されることはありません。

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

、のためので、私はいつも私のencodeBeginメソッド内nameプロパティのnullを取得します。デバッグ後、私はsetNameメソッドが呼び出されないことに気付きました。私はELのことを考えているかもしれないと思っていましたが(そして私はまだその理由がそれに関係していると信じています)、本当に変わったのは、idのプロパティがうまくいきます。セッターが呼び出され、開始されます。

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

私のコンポーネントには何が欠けていますか?

答えて

12

この動作は仕様および仕様により予告されています。値式である属性値はUIComponent#setValueExpression()によって設定されます。つまり、通常はビューのレンダリング時にが使用されたときにのみ評価されるはずです。

id(およびbinding)属性は、特別な処理があります:それは前にビューのビルド時中に評価の視点のレンダリングので、それ以外の場合はクラッシュしていました(「通常」のセッターではなくsetValueExpression()で呼ばれることになるので、設定されていますid(またはbinding)属性が、何らかの理由でビューの作成時と異なる値に動的に評価された場合)。

getter/setterをローカルプロパティではなくUIComponent#getStateHelper()に委任する方がよいでしょう。 setValueExpression()は最終的にStateHelperにもなります(データが必要な場合はゲッターを呼び出してください)、getAttributes()StateHelperの値も解決します。彼らはすでにあなたがしているから延びるUIComponentBaseスーパークラスでdefiniedしているので、あなたが安全にgetId()setId()メソッドを削除することができます

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

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

注意。

+0

ありがとうございます!私は、私のコンポーネント内のさまざまなタイプの属性値を区別するための特別なメソッドを実装する必要があるかどうかを質問したいと思います。 (私はUIComponentBaseがそれを独自に処理することを理解しました)そして、もしそうなら、それを行うベストプラクティスはありますか? – RaresI

+0

いいえ、一般的には気にしないでください。(評価された)属性値を取得するには、単にゲッターを呼び出します。 – BalusC

関連する問題