2010-11-18 15 views
3

Ayons un composant composite extrêmement simple:JSF 2.0: Pourquoi un bean JSF est-il créé lorsqu'il est utilisé dans un composant qui n'est pas rendu?

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

Bean pour elle:

public class TestBean { 

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

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

} 

appellent ensuite comme d'habitude, mais ne montrent pas:

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

Qu'est-ce qui se passe est que le composant n'est jamais rendu et que le bean n'est jamais initié comme on le supposerait.

Cependant, si l'on change le composant comme:

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

Ce qui se passe est que le composant obtient toujours jamais rendu (parce que l'attribut rendered est false), cependant, le haricot ne soit instancié. Cela se produit toujours lorsque nous utilisons une propriété bean dans un composant JSF natif (h:panelGroup, h:inputHidden, peu importe).

Pourquoi est-ce vrai?

Répondre

6

Les composants (et tous les beans liés) sont créés lors de la création de la vue. L'attribut rendu est évalué uniquement pendant le temps de rendu de la vue. Cela a toujours fonctionné de cette manière dans JSF.

Si le bean fait un travail coûteux pendant la construction, alors je suggère de laisser ce travail coûteux dépend de la condition que vous réutilisez dans l'attribut rendu.

+0

Merci BalusC, je savais que c'était quelque chose de fondamental mais pas exactement quoi. Ne vous sentez-vous pas mal pour créer des composants et des haricots quand ils ne sont même pas utilisés? –

+0

Donc, je suppose que la seule façon de contourner cela est d'utiliser UIComponents au lieu de composants composites:/S'il vous plaît corrigez-moi, si mal. –

+0

Juste essayé un hack autour de ceci: utilisez un ui: répétez avec 0-1 éléments en fonction de si vous voulez que le contenu soit initialisé ou non. J'ai créé une méthode dans le backing pour retourner une liste vide quand le contenu ne devrait pas être créé et retourner un seul élément fictif (quel qu'il soit) dans une liste quand le contenu est censé être créé et rendu. Il bloque un peu l'arbre des composants, mais devrait au moins fonctionner dans les cas de base. –