JSF 2 <f: selectItems> не распознает атрибуты itemLabel и itemValue - PullRequest
3 голосов
/ 04 октября 2011

У меня есть следующее выпадающее меню на странице Facelets:

<h:selectOneMenu value="#{contactBean.selectedContact}" converter="#{contactConverter}">
    <f:selectItems value="#{contactsHolder.contacts}" var="contact"
    itemLabel="#{contact.firstName}" itemValue="#{contact}" />
</h:selectOneMenu>

Проблема в том, что независимо от того, что я вставил для itemLabel (выражение JSF EL или просто текст), оно не отображается. Есть идеи, что я делаю не так?

Вот ContactConverter:

@ManagedBean(name = "contactConverter")
@RequestScoped
public class ContactConverter implements Converter, Serializable {
    @ManagedProperty(value = "#{contactsHolder}")
    private ContactsHolder contactsHolder;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        return contactsHolder.getContacts().get(value);
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        return ((Contact) value).getContactID();
    }
    //getter & setters...
}

А ContactsHolder:

@ManagedBean
@SessionScoped
public class ContactsHolder implements Serializable {
    private Map<String, Contact> contacts;

    @PostConstruct
    public void init() {
        contacts = new LinkedHashMap<String, Contact>();
        //get Contacts data and populate map...
    }
    //getters & setters...
}

1 Ответ

12 голосов
/ 04 октября 2011

Вы кормите от Map<String, Contact> до <f:selectItems value>. Каждый элемент в атрибуте var будет Map.Entry<String, Contact>, который имеет только методы getKey() и getValue(), возвращающие ключ карты String и значение карты Contact соответственно. Класс Map.Entry действительно не имеет метода getFirstName().

Исправьте это соответствующим образом:

<f:selectItems value="#{contactsHolder.contacts}" var="contact"
    itemLabel="#{contact.value.firstName}" itemValue="#{contact.value}" />

Или, если вы нацелены на контейнер с сервлетом 3.0 / EL 2.2, который позволяет вызывать методы, не являющиеся получателями, так что вы можете использовать Map#values(), чтобы получить Collection<Contact>:

<f:selectItems value="#{contactsHolder.contacts.values()}" var="contact"
    itemLabel="#{contact.firstName}" itemValue="#{contact}" />

Или, вместо этого, сделайте #{contactsHolder.contacts} a List<Contact>, чтобы ваш первоначальный код представления работал:

<f:selectItems value="#{contactsHolder.contacts}" var="contact"
    itemLabel="#{contact.firstName}" itemValue="#{contact}" />
...