Martin Magakian
Martin Magakian

Reputation:

ForEach and Facelets

My managed bean :

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;
}

My forEach :

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

My output stream :
I'm here...
I'm here...
I'm here...
I'm here...

As you can see "getLiQuickNav( )" is call 4times by my ForEach. But I just wan't to call "getLiQuickNav( )" one time... How to call it just one time ?

Bonus question: Why "getLiQuickNav( )" is call 4time whereas I have only 3item "tata,titi,toto" ?

Thank's

Upvotes: 0

Views: 1293

Answers (3)

mtpettyp
mtpettyp

Reputation: 5569

You can't control the number of times that getLiQuickNav() is called - consider caching your list so it isn't rebuilt between calls.

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;
}

As well you should be using <ui:repeat/> rather than <c:forEach/>. See this blog entry for why.

Upvotes: 3

GreenieMeanie
GreenieMeanie

Reputation: 3610

Getter's in Java (in any context, to include for Faces Managed Beans) should not generate anything - they should just return a value. Create the list before hand and return it.

Upvotes: 2

cwash
cwash

Reputation: 4245

Answer

You're reinitializing the state in a getter every time. That is meant to be an accessor, not a way to initialize state. Don't create the list in getLiQuickNav, create in a constructor or setter.

Bonus

The first time you call getLiQuickNav() you initialize the list, the reference to this list gets returned and stored in a scope to evaluate your expression (.liQuickNav) and then the getLiQuickNav() is called by convention 3 more times for each item in the list.

It should get called once if you return the same list every time. You're returning a new one every time.

Upvotes: 2

Related Questions