2010-11-18 7 views
3

JSF 2.0:レンダリングされていないコンポーネントでJSF Beanを使用すると、そのコンポーネントが作成されるのはなぜですか?

<cc:implementation> 
    #{testBean.someField} 
</cc:implementation> 

それのためのBean:

public class TestBean { 

    private boolean someField = false; 
    public boolean getSomeField() { return someField; } 

    @PostConstruct 
    public void init() { 
     System.out.println("PostConstruct"); 
    } 

} 

それから通常のように呼び出してください:

<codeEditor:test rendered="#{false}" /> 

コンポーネントは決してレンダリングされず、Beanは決して想定どおりに開始されません。

ただし、コンポーネントを次のように変更した場合:

<cc:implementation> 
    <h:outputText value="#{testBean.someField}" /> 
</cc:implementation> 

コンポーネントがまだレンダリングされないのは(rendered属性がfalseなので)、インスタンス化されます。これは、ある種のネイティブJSFコンポーネント(h:panelGrouph:inputHiddenなど)内でBeanプロパティを使用すると常に発生します。

なぜそうですか?

答えて

6

コンポーネント(およびすべてのバインドBean)は、ビューの作成時に作成されます。レンダリングされた属性は、ビューのレンダリング時にのみ評価されます。それはJSFでいつもそうしてきました。

ビーンが建設中に高価な仕事をしている場合は、高価な仕事をレンダリングされた属性で再利用するいくつかの条件に依存させることをお勧めします。

+0

ありがとうBalusC、私はそれが何か基本的なものだとはっきりとは分かっていませんでした。あなたが使用されていなくても、コンポーネントとBeanを作成するのに悪いと感じませんか? –

+0

これは、複合コンポーネントではなくUIComponentsを使用する唯一の方法だと思います。 –

+0

ちょうどこれをハックしようとしました。内容を初期化するかどうかによって、0-1要素のui:repeatを使用します。コンテンツを作成してはならないときは空のリストを返し、コンテンツが作成されレンダリングされるはずのリストの中に単一のダミー要素(何でも)を返すメソッドをバッキングに作成しました。それはコンポーネントツリーを少し膨らませますが、少なくとも基本的なケースではうまくいくはずです。 –

関連する問題