JSF 2: группировка выбора с помощью SelectItemGroup + POJO - PullRequest
7 голосов
/ 29 декабря 2010

Я пытался работать с сгруппированными выделениями примерно так:

<h:selectOneMenu value="#{selectionLabBean.oneSelectMenuGroup}"
    id="SelectOneMenuGroup" >
        <f:selectItems value="#{selectionLabBean.heroGroupList}" />
</h:selectOneMenu>
<p:message for="SelectOneMenuGroup" />

где heroGroupList выглядит примерно так:

SelectItem[] heroArr = new SelectItem[] {
    new SelectItem("Paladin"),
    ...
};
heroListWithGrouping.add(
    new SelectItemGroup("Human", 
        "A collection of human race Heroes", 
        false,
        heroArr
    )
);
.....

И мне интересно, могу ли я сделать такую ​​группировку с POJO вместо объектов SelectItem?

Если я не смог достичь этого, я думаю, что мне нужно каким-то образом преобразовать мои доменные объекты или результаты моего запроса в массивы SelectItem, чтобы он работал.

Есть идеи?

Ответы [ 2 ]

9 голосов
/ 29 декабря 2010

Это действительно невозможно, если вы хотите использовать SelectItemGroup.Вам нужно конвертировать из коллекции POJO в List<SelectItem> в двойном цикле for во время построения (post) компонента.

@PostConstruct
public void init() {
    List<HeroRace> heroRaces = getItSomehowFromDatabase();
    this.heroGroupList = new ArrayList<SelectItem>();
    for (HeroRace heroRace : heroRaces) {
        SelectItemGroup group = new SelectItemGroup(heroRace.getName()); // Human, etc
        List<SelectItem> heroes = new ArrayList<SelectItem>();
        for (Hero hero : heroRace.getHeroes()) {
            heroes.add(new SelectItem(hero.getName()); // Paladin, etc
        }
        group.setSelectItems(heroes.toArray(new SelectItem[heroes.size()]));
        this.heroGroupList.add(group);
    }
}

Вы также можете использовать Hero в качестве значения элемента

heroes.add(new SelectItem(hero, hero.getName()); // Paladin, etc

, чтобы вы могли связать #{selectionLabBean.oneSelectMenuGroup} с типом Hero вместо String.Но тогда вам нужно предоставить Converter.На эту часть уже ответил Аморфис.

4 голосов
/ 29 декабря 2010

Да, вы можете вернуть список или массив POJO вместо SelectItems.Для этого вам понадобится конвертер, но это не имеет большого значения.Итак, сначала конвертер:

@FacesConverter(forClass=Hero.class)
public class HeroConverter implements Converter {

  @Override
  public Object getAsObject(FacesContext context, UIComponent component, String value) {
      return new Hero(value);
  }

  @Override
  public String getAsString(FacesContext context, UIComponent component, Object value) {
      return ((Hero)value).getName();
  }
}

Теперь, если вы возвращаете список от Hero es до <f:selectItems>, у вас есть опции в HTML, где label - Hero.toString(), а значение возвращается из HeroConverter.getAsString().

Еще одна вещь.Если вы передаете какое-то значение для этого выбора, JSF преобразует его в объект и проверяет (методом equals ()), был ли этот объект в списке объектов для выбора.Так что в случае выше, вам нужно переопределить equals() в Hero, чтобы проверить, совпадают ли имена.Другое решение состоит не в создании нового экземпляра в getAsObject, а в сохранении где-нибудь списка доступных Hero es, возвращении этого списка в <f:selectionItems> и возврате объекта из этого списка в getAsObject().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...