两个不同的SelectItem返回单个选定值

时间:2013-02-19 07:33:51

标签: jsf

我有一个国家级:

public class Country{
     private Long id;
     private String name;
}

和具有两个国家/地区字段的人员类

public class Person{
    private Country nationality;
    private Country nationality2;
}

现在在JSF中,我使用<f:selectItems>返回选择国籍的国家/地区列表,如下所示:

<h:form id="form1">
    <h:selectOneMenu value="#{mybean.person.nationality.id}">
         <f:selectItems value="#{mybean.countryList}" var="var" itemValue="#{var.id}"/>
    </h:selectOneMenu>

    <h:selectOneMenu value="#{mybean.person.nationality2.id}">
         <f:selectItems value="#{mybean.countryList}" var="var" itemValue="#{var.id}"/>
    </h:selectOneMenu>
    <p:commandButton actionListener="#{mybean.save}" update="sometable @form"/>
</h:form>

现在奇怪的问题是,当我提交表格时,分配给第二个字段(国籍2)的值被分配给国籍和国籍2,而不管第一个字段选择了什么。例如,当我提交表单selected value for nationality is 1时,selected value for nationality2 is 2both fields have the value 2。为什么会这样?

PS:JSF实现是Mojarra 2.1.3

2 个答案:

答案 0 :(得分:2)

导致您的具体问题是因为您将相同Country引用的副本设置为选定值,然后仅操作id属性。在一个引用中进行的所有更改也会反映在所有其他引用中。

E.g。

Country country = new Country();
person.setNationality1(country);
person.setNationality2(country);
country.setId(1); // Gets reflected in both nationalities!

您最好将整个Country实体设置为值,而不是操纵其属性。创建一个Converter,可在Countryid之间进行转换:

@FacesConverter(forClass=Country.class)
public class CountryConverter implements Converter {

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        return (value instanceof Country) ? ((Country) value).getId() : null;
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (value == null || value.isEmpty()) {
            return null;
        }

        if (!value.matches("\\d+")) {
            throw new ConverterException(new FacesMessage("Invalid country ID: " + value));
        }

        Long countryId = Long.valueOf(value);
        MyBean myBean = context.getApplication().evaluateExpressionGet(context, "#{myBean}", MyBean.class);

        for (Country country : myBean.getCountries()) {
            if (countryId.equals(country.getId())) {
                return country;
            }
        }

        throw new ConverterException(new FacesMessage("Unknown country ID: " + value));
    }

}

并按如下方式使用:

<h:selectOneMenu value="#{mybean.person.nationality1}">
     <f:selectItems value="#{mybean.countries}" var="country" itemValue="#{country}" itemLabel="#{country.name}" />
</h:selectOneMenu>
<h:selectOneMenu value="#{mybean.person.nationality2}">
     <f:selectItems value="#{mybean.countries}" var="country" itemValue="#{country}" itemLabel="#{country.name}" />
</h:selectOneMenu>

答案 1 :(得分:1)

尝试为selectOneMenu提供第二个var其他名称。例如:

<h:selectOneMenu value="#{mybean.person.nationality2.id}">
         <f:selectItems value="#{mybean.countryList}" var="var2" itemValue="#{var2.code}"/>
    </h:selectOneMenu>

否则,您可以通过更改第二个var来覆盖(第一个)变量selectOneMenu中的更改。

修改
如果它没有解决问题,请尝试测试以创建第二个countryList(countryList2)并将其附加到第二个selectOneMenu

如果值仍然保持不变,则失败必须在getter或setter中。