2009-06-03 3 views
0

Мой управляемый компонент:ForEach и 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; 
} 

Мой Foreach:

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

Мой выходной поток:
Я здесь ...
Я здесь ...
Я здесь ...
Я здесь ...

Как вы можете видеть, «getLiQuickNav()» - это вызов 4 раза моим ForEach. Но я просто не позвонил «getLiQuickNav()» один раз ... Как назвать это всего один раз?

Вопрос о бонусе: Почему «getLiQuickNav()» является вызовом 4 раза, тогда как у меня есть только 3item «tata, titi, toto»?

Спасибо-х

ответ

3

Вы не можете контролировать количество раз, что getLiQuickNav() называется - рассмотреть кэширование списка, так что не перестроен между вызовами.

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

Как вы должны использовать <ui:repeat/>, а не <c:forEach/>. См. Эту запись blog.

+0

Я не думаю, что что-то вроде выше - хорошая практика в целом. Нет причин для ленивой инициализации чего-либо с 3-мя элементами. Построить список в конструкторе или статическом блоке. – GreenieMeanie

+0

@ GreenieMeanie - это, очевидно, тривиальный пример, возможно, что фактические данные списка будут * не * доступны для построения объекта или инициализации статического блока (т. Е. Если он был извлечен из некоторого внешнего источника, такого как база данных). Ответ должен был показать, что построение списка не должно выполняться при каждом вызове getLiQuickNav(). – mtpettyp

2

Ответ

Вы переинициализация состояния в поглотителе каждый раз. Это предназначено для доступа, а не для инициализации состояния. Не создавайте список в getLiQuickNav, создавайте в конструкторе или сеттере.

Bonus

Первый раз, когда вы звоните getLiQuickNav() инициализации списка, ссылка на этот список получает возвращается и хранится в области, чтобы оценить ваше выражение (.liQuickNav), а затем getLiQuickNav() называется конвенцией более 3 раз для каждого элемента в списке.

Он должен называться один раз, если вы возвращаете тот же список каждый раз. Вы возвращаете новый каждый раз.

2

Getter's in Java (в любом контексте, чтобы включить для управляемых фаз), не должен генерировать ничего - они должны просто вернуть значение. Создайте список перед раздачей и верните его.