当项目值设置为对象时,selectOneMenu将不会更新

时间:2015-04-16 01:27:11

标签: jsf-2 primefaces

我试图使用primefaces 5.2创建一个selectOneMenu,列表项是从数据库加载的,它们的类型是一个包含其他属性的Object,我想复制the primefaces showcase method(高级一个) ),但从未分配选定的值,这是我的代码:

 <h:form id="f">
                    <p:selectOneMenu id="advanced" value="#{expertiseController.selectedExpertise}" converter="expertiseConverter">
                        <f:selectItems value="#{expertiseController.expertises}" var="exp" itemLabel="#{exp.id}" itemValue="#{exp}" />
                        <p:ajax update="test" />
                    </p:selectOneMenu>

                    <p:outputLabel id="test" value="#{expertiseController.selectedExpertise.id}"/>
                </h:form>

豆子:

@Named(value = "expertiseController")
@ViewScoped
public class ExpertiseController implements Serializable {

    private Expertise selectedExpertise = new Expertise();
    private List<Expertise> expertises = Expertise.getAllExpertiseTypes();
....
getters ..

转换器:

FacesConverter("expertiseConverter")
public class ExpertiseConverter implements Converter {

    public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
        if(value != null && value.trim().length() > 0) {
            try {
                return Expertise.getById(value);
            } catch(Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        else {
            return null;
        }
    }

    public String getAsString(FacesContext fc, UIComponent uic, Object object) {
        if(object != null) {
            return String.valueOf(((Expertise) object).getId());
        }
        else {
            return null;
        }
    }   
}   

但是从未设置outputLabel,并且永远不会触发selectedExpertise的setter方法。 现在这只发生在我将itemValue设置为#{exp}时,但是当我将它设置为#{exp.id}(并更改selectOneMenu值)时,一切正常。 我甚至检查了转换器的值,它们都很好。 问题是,当我尝试使用primefaces示例时,它运行良好!当我把它更改为我的对象并转换它dosnt!

我在这里错过了什么或做错了什么?

更新 我只是想通了你必须在转换器中返回列表中的相同对象,这就是我所做的, 我在ExpertiseController中注入ExpertiseConverter,然后我循环遍历ExpertiseController的列表并返回相同的对象(我猜的是相同的地址),这里是代码:

import com.medisecretaire.controller.ExpertiseController;
import com.medisecretaire.model.Expertise;
import java.io.Serializable;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;

@FacesConverter("expertiseConverter")
public class ExpertiseConverter implements Converter, Serializable {

    @Inject
    private ExpertiseController controller;


    public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
        System.out.println(controller.getExpertises());
        if(value != null && value.trim().length() > 0) {
            try {
                for (Expertise expertise : controller.getExpertises()) {
                    if(expertise.getId().equalsIgnoreCase(value)){
                        return expertise;
                    }
                }

                return null;
            } catch(Exception e) {
                return null;
            }
        }
        else {
            return null;
        }
    }

    public String getAsString(FacesContext fc, UIComponent uic, Object object) {
        if(object != null) {
            return String.valueOf(((Expertise) object).getId());
        }
        else {
            return null;
        }
    }   
}       

但有更好的方法吗?我不喜欢&#34;注射&#34;部分......还是正常的?

更新2: 当我添加filter="true"时,它不再起作用......这令人困惑......

更新3: 我知道有更好的方法!所以我抓住了UIComponent提取的SelectOneMenu迭代了它的子节点并找到UISelectItems,从那里我发现存储在列表中的相同对象,这里是代码:

public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
        List list = null;

        SelectOneMenu menu = (SelectOneMenu) uic;
        for (UIComponent comp : menu.getChildren()) {
            if (comp instanceof UISelectItems) {
                UISelectItems item = (UISelectItems) comp;
                if (item.getValue() instanceof List) {
                    list = (List) item.getValue();
                }
            }
        }
        //Do something with the list

并且现在使用filer属性。

0 个答案:

没有答案