首页 > 解决方案 > selectonemenu 不将值传递给 setter 函数

问题描述

selectOneMenu 调用 setter 方法,但始终传递一个null值。事件侦听器最终将使用所选植物 ID 更新会话变量,但现在只记录该值。我试图添加一个转换器来管理对象,但是当我在 selectOneMenu 中设置它时,页面失败并显示:

Class com.sun.faces.application.ApplicationImpl can not access a member of class com.conagra.data.PlantsConverter with modifiers ""

在 Tomcat 9 上使用 Primefaes 6.2。

xhtml

...
<p:selectOneMenu id="plantList"
    value="#{userPlantsBean.selectedPlant}" height="250" effect="fade"
    style="padding:0;" converter="plantsConverter"
    rendered="#{plants != 1 and view.viewId != '/Login.xhtml'}">
    <f:selectItem itemLabel="#{plantName}" itemValue="#{userPlantsBean.selectedPlant}"
        style="padding:0"  />
    <f:selectItems value="#{userPlantsBean.userPlantsList}"
        var="plant" itemLabel="#{plant.plantDesc}"
        itemValue="#{plant}" />
    <p:ajax event="change" listener="#{userPlantsBean.onPlantChange}"  />
</p:selectOneMenu>
...

...
public List<Plants> getUserPlantsList() {
    ...
}

public Plants getSelectedPlant() {
    return selectedPlant;
}

public void setSelectedPlant(Plants selectedPlant) {
    this.selectedPlant = selectedPlant;
}

public void onPlantChange(AjaxBehaviorEvent e) {
    logger.debug(selectedPlant);
}
...

转换器

...
@FacesConverter(value="plantsConverter")
public class PlantsConverter implements Converter {
    private List<Plants> plantsList;

    PlantsConverter(){
        plantsList = new UserPlantsBean().getUserPlantsList();
    }

    @Override
    public Object getAsObject(FacesContext facesContext, UIComponent component, String submittedValue) {
        if (submittedValue.trim().equals("")) {
            return null;
        } else {
            try {
                for (Plants p : plantsList) {
                    if (p.getPlantID() == submittedValue) {
                        return p;
                    }
                }
            } 
            catch (NumberFormatException exception) {
                throw new ConverterException(
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid plant"));
            }
        }
        return null;
    }

    @Override
    public String getAsString(FacesContext facesContext, UIComponent componet, Object value) {
        if (value == null || value.equals("")) {
            return "";
        } else {
            return String.valueOf(((Plants) value).getPlantID());
        }
    }
}

生成的选择html

<select id="plantList_input" name="plantList_input" tabindex="-1" aria-hidden="true" onchange="PrimeFaces.ab({s:&quot;plantList&quot;,e:&quot;change&quot;,p:&quot;plantList&quot;});">
    <option value="com.conagra.data.Plants@6a98fdfb">RENSSELAER PLANT</option>
    <option value="com.conagra.data.Plants@7785b2d0">ARCHBOLD PLANT</option>
    <option value="com.conagra.data.Plants@3e184b2b">LAKEVILLE PLANT</option>
    <option value="com.conagra.data.Plants@2279b29e">MAPLE GROVE PLANT</option>
    <option value="com.conagra.data.Plants@3adb3875">MILTON PLANT &amp; RYDER LOGISTICS</option>
    <option value="com.conagra.data.Plants@60921ecc">OAKDALE PLANT</option>
    <option value="com.conagra.data.Plants@1caf40e6">ONTARIO IMC</option>
    <option value="com.conagra.data.Plants@73adecaf">RUSSELLVILLE PLANT</option>
</select>

标签: jsfprimefacesselectonemenu

解决方案


首先, selectedPlant 应该是 Plant 对象,而不是 DataTableColumn 对象:

public Plant getSelectedPlant() {
   return selectedPlant;
}
public void setSelectedPlant(Plant selectedPlant) {
   this.selectedPlant = selectedPlant;
}

之后,您必须设置对象,而不是对象的属性。

<p:selectOneMenu id="plantList"
   value="#{userPlantsBean.selectedPlant}" height="250" effect="fade"
   style="padding:0;" converter="plantConverter"
   rendered="#{plants != 1 and view.viewId != '/Login.xhtml'}">
   <f:selectItems value="#{userPlantsBean.userPlantsList}"
       var="plant" itemLabel="#{plant}"
       itemValue="#{plant}" />
   <p:ajax event="change" listener="#{userPlantsBean.onPlantChange}"  />
</p:selectOneMenu>

最后,您必须实现一个允许将值转换为 Plant 对象的 PlantConverter。


推荐阅读