2010-12-29 26 views
7

Tôi đã cố gắng làm việc với các lựa chọn nhóm với một cái gì đó như thế này:JSF 2: Lựa chọn nhóm với SelectItemGroup + POJO

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

nơi heroGroupList là một cái gì đó như thế này:

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

Và i' m trái tự hỏi nếu tôi có thể làm loại nhóm với POJOs thay vì các đối tượng SelectItem?

Nếu tôi không thể đạt được điều này, tôi nghĩ rằng tôi phải bằng cách nào đó chuyển đổi các đối tượng miền của tôi hoặc kết quả truy vấn của tôi thành mảng của SelectItem để làm cho nó hoạt động.

Bất kỳ ý tưởng nào?

Trả lời

9

Điều đó thực sự không thể thực hiện được khi bạn muốn sử dụng SelectItemGroup. Bạn cần phải chuyển đổi từ bộ sưu tập POJO thành List<SelectItem> trong một vòng lặp đôi trong khi xây dựng bean (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); 
    } 
} 

Bạn cũng có thể sử dụng Hero như giá trị mục

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

để bạn có thể ràng buộc #{selectionLabBean.oneSelectMenuGroup} đến một loại Hero thay vì String. Nhưng sau đó bạn cần cung cấp Converter. Phần đó đã được Amorfis trả lời.

+0

Vì vậy, kết luận là: để sử dụng lựa chọn nhóm, chúng ta phải chuyển đổi POJO thành Danh sách . Nhưng chúng ta vẫn có thể sử dụng POJO làm itemValue với bộ chuyển đổi. Coooool! Cảm ơn bạn BalusC. – bertie

+0

Tôi đã thử ràng buộc nó vào loại Hero, nhưng nó thất bại với lỗi: SelectOneMenuGroup: Validation Error: Giá trị không hợp lệ, điều này thật lạ, vì tôi không sử dụng bất kỳ xác nhận nào cả. .. Và tại managedbean, liên kết là: private HeroBean oneSelectMenuGroupPojo; Tôi gỡ lỗi nó và phát hiện ra các proggie doesnt đặt giá trị ràng buộc. Tôi đã thử var = "hero" itemValue = "# {hero}" itemLabel = "# {hero.name}", nhưng cũng thất bại. – bertie

+0

Điều này có thể xảy ra bất cứ khi nào mục được chọn không khớp với bất kỳ mục nào trong danh sách theo phương thức 'equals()'. Có khả năng phương thức 'equals()' không được triển khai hoặc thực hiện kém. – BalusC

4

Có, bạn có thể trả về Danh sách hoặc mảng POJO thay vì SelectItems. Bạn sẽ cần bộ chuyển đổi để làm việc này, nhưng nó không phải là một việc lớn. Vì vậy, chuyển đổi đầu tiên:

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

Bây giờ nếu bạn quay trở lại danh sách các Hero es để <f:selectItems>, bạn có các tùy chọn trong HTML nơi nhãn là Hero.toString(), và giá trị được trả về từ HeroConverter.getAsString().

Một điều nữa. Nếu bạn gửi một số giá trị cho lựa chọn này, JSF chuyển đổi nó thành đối tượng và kiểm tra (bằng phương thức equals()) nếu đối tượng này nằm trong danh sách các đối tượng để chọn. Vì vậy, trong trường hợp trên, bạn cần ghi đè equals() trong Hero để kiểm tra xem tên có bằng nhau không. Một giải pháp khác không phải là tạo cá thể mới trong getAsObject, nhưng để giữ một nơi nào đó trong danh sách có sẵn Hero es và trả lại danh sách này thành <f:selectionItems> và trả về đối tượng từ danh sách này trong getAsObject().

+0

Cảm ơn bạn rất nhiều. Điều này bằng điều và không tạo ra một thể hiện mới là một cái gì đó mới đối với tôi trong việc hiểu các trình biến đổi JSF. Chúc một ngày tốt lành ! – bertie

Các vấn đề liên quan