2009-06-03 8 views
0

Mon managed bean:ForEach et Facelets

public List<String> getLiQuickNav(){ 

    System.out.println("I'm here..."); 

    List<String> l = new ArrayList<String>(); 
    l.add("toto"); 
    l.add("tata"); 
    l.add("titi"); 
    return l; 
} 

Mon forEach:

<c:forEach var="categorie" items="#{mainControleur.liQuickNav}"> 
    <h:outputLabel value="${categorie}"/> 
</c:forEach> 

Mon flux de sortie:
Je suis ici ...
Je suis ici ...
Je suis ici ...
Je suis ici ...

Comme vous pouvez le voir "getLiQuickNav()" est appelé 4times par mon ForEach. Mais je veux juste appeler "getLiQuickNav()" une fois ... Comment l'appeler juste une fois?

Question de bonus: Pourquoi "getLiQuickNav()" est appelé 4time alors que je n'ai que 3item "tata, titi, toto"?

Répondre

3
Remercions

Vous ne pouvez pas contrôler le nombre de fois que getLiQuickNav() est appelé - considérer la mise en cache de votre liste de sorte qu'il ne soit pas reconstruit entre les appels.

private List<String> l; 

public List<String> getLiQuickNav() 
{ 
    if (l == null) 
    { 
      System.out.println("I'm here..."); 

      l = new ArrayList<String>(); 
      l.add("toto"); 
      l.add("tata"); 
      l.add("titi"); 
    } 
    return l; 
} 

De plus, vous devriez utiliser <ui:repeat/> plutôt que <c:forEach/>. Voir cette blog entrée pour pourquoi.

+0

Je ne pense pas que quelque chose comme ci-dessus est une bonne pratique en général. Il n'y a aucune raison d'initialiser paresseusement quelque chose avec 3 éléments. Construisez la liste dans le constructeur ou un bloc statique. – GreenieMeanie

+0

@GreenieMeanie - Ceci est évidemment un exemple trivial, il y a de fortes chances que les données de la liste ne soient pas disponibles sur la construction de l'objet ou l'initialisation du bloc statique (si elle provient d'une source externe telle qu'une base de données). La réponse était destinée à illustrer que la construction de la liste ne devrait pas être faite à chaque appel de getLiQuickNav(). – mtpettyp

2

Réponse

Vous réinitialisez l'état dans un getter à chaque fois. Cela est censé être un accesseur, pas un moyen d'initialiser l'état. Ne créez pas la liste dans getLiQuickNav, créez dans un constructeur ou un setter.

Bonus

La première fois que vous appelez getLiQuickNav() vous initialisez la liste, la référence à cette liste est renvoyée et stockée dans un champ pour évaluer votre expression (.liQuickNav), puis le getLiQuickNav() est appelé par convention 3 plus fois pour chaque élément de la liste.

Il doit être appelé une fois si vous renvoyez la même liste à chaque fois. Vous en retournez un nouveau à chaque fois.

2

Getter's dans Java (dans n'importe quel contexte, à inclure dans Faces Managed Beans) ne devrait pas générer quoi que ce soit - ils devraient juste retourner une valeur. Créez la liste avant la main et renvoyez-la.