2010-12-29 4 views
7

이 같은 뭔가 그룹화 된 선택 작업을 시도했다 :JSF 2 : 선택 SelectItemGroup + POJO로 그룹화

<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 
    ) 
); 
..... 

그리고 내가 ' 내가 SelectItem 객체 대신 POJO를 사용하여 이러한 종류의 그룹화를 할 수 있는지 궁금합니다.

내가 이것을 달성 할 수 없다면, 어떻게 든 내 도메인 개체 또는 내 쿼리 결과를 SelectItem 배열로 변환하여 작동하도록해야한다고 생각합니다.

아이디어가 있으십니까?

답변

9

SelectItemGroup을 사용하려는 경우 실제로는 불가능합니다. 빈의 (포스트) 생성 중에 POJO 컬렉션을 double for-loop로 List<SelectItem>으로 변환해야합니다.

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

당신은 또한 당신이 대신 StringHero 유형 #{selectionLabBean.oneSelectMenuGroup}을 결합 할 수

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

때문에 항목 값으로 Hero을 사용할 수 있습니다. 하지만 Converter을 제공해야합니다. 그 부분은 이미 Amorfis에 의해 답변되었습니다.

+0

결론적으로 그룹화 된 선택을 사용하려면 POJO를 List 으로 변환해야합니다. 그러나 우리는 여전히 POJO를 변환기가있는 itemValue로 사용할 수 있습니다. 쿠오 룩! BalusC에 감사드립니다. – bertie

+0

히어로 유형에 바인딩하려고했지만 오류로 인해 실패했습니다. SelectOneMenuGroup : 유효성 검사 오류 : 값이 유효하지 않습니다. 유효성 검사를 전혀 사용하지 않아 이상합니다. .. 그리고 managedbean에서 바인딩은 다음과 같습니다. private HeroBean oneSelectMenuGroupPojo; 나는 그것을 디버깅했고 proggie doesnt가 ​​바인딩 값을 설정한다는 것을 알았다. var = "hero"itemValue = "# {hero}"itemLabel = "# {hero.name}"시도했지만 실패했습니다. – bertie

+0

선택한 항목이 목록의 항목 중 하나와 일치하지 않을 때마다 'equals()'메소드를 사용하여이 작업을 수행 할 수 있습니다. 'equals()'메소드가 구현되지 않았거나 제대로 구현되지 않았을 가능성이 있습니다. – BalusC

4

예, SelectItems 대신 POJO 목록 또는 배열을 반환 할 수 있습니다. 이 작업을하려면 변환기가 필요 하겠지만 큰 문제는 아닙니다. 그래서 먼저 계산기 : 당신이 <f:selectItems>Hero ES의 목록을 반환하는 경우 레이블 Hero.toString()이며, 값이 HeroConverter.getAsString()에서 반환되는 경우

@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(); 
    } 
} 

지금, 당신은 HTML의 옵션이 있습니다.

한 가지 더. 이 선택 항목에 대해 약간의 값을 제출하면 JSF는 이것을 객체로 변환하고이 객체가 선택 대상 객체 목록에있는 경우 equals() 메소드로 검사합니다. 따라서 위의 경우 equals()Hero에 덮어 써야 이름이 같은지 확인해야합니다. 또 다른 해결책은 getAsObject에 새 인스턴스를 만들지 않고 사용 가능한 Hero의 어딘가의 목록을 유지하고이 목록을 <f:selectionItems>에 반환하고이 목록의 개체를 getAsObject()에 반환하는 것입니다.

+0

정말 고마워요. 이것은 새로운 JSF 변환기를 이해하는 데있어서 새로운 것입니다. 좋은 하루 되세요! – bertie