1

我仍然有 selectManyCheckBox 的问题..

多选复选框:

 <p:selectManyCheckbox converter="genericEnumConverter" value="#{aView.newObject.aValue}">                                           
        <f:selectItems value="#{enumBean.aValueValues}" var="s" itemValue="#{s}" itemLabel = "#{s.name}"/>
 </p:selectManyCheckbox> 

此 selectManyCheckBox 的转换器与此处描述的相同: Use enum in h:selectManyCheckbox

@FacesConverter("genericEnumConverter")
public class GenericEnumConverter implements Converter {

    private static final String ATTRIBUTE_ENUM_TYPE = "GenericEnumConverter.enumType";

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        System.out.println("getAsString 1: ");
        if (value instanceof Enum) {
            System.out.println("getAsString 2: ");
            component.getAttributes().put(ATTRIBUTE_ENUM_TYPE, value.getClass());
            System.out.println("getAsString 3: ");
            return ((Enum<?>) value).name();
        } else {
            System.out.println("getAsString 4: ");
            throw new ConverterException(new FacesMessage("Value is not an enum: " + value.getClass()));
        }        
    }

    @Override
    @SuppressWarnings({"rawtypes", "unchecked"})
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        System.out.println("getAsObject 1: ");
        Class<Enum> enumType = (Class<Enum>) component.getAttributes().get(ATTRIBUTE_ENUM_TYPE);
        System.out.println("getAsObject 2: ");
        try {
            System.out.println("getAsObject 3: ");
            return Enum.valueOf(enumType, value);
        } catch (IllegalArgumentException e) {
            System.out.println("getAsObject 4: ");
            throw new ConverterException(new FacesMessage("Value is not an enum of type: " + enumType));
        }
    }

枚举是:

public enum aValue {

        1Value,
        2Value,
        3Value,
        4Value;
        private final String name;

        private aValue() {
            System.out.println("aValue 1");
            this.name = null;
            System.out.println("aValue 2");
        }

        public String getName() {
            System.out.println("getName 1 " + name());
            return ResourceBundleUtil.getLabelFromRb("aValue." + name());
        }
    }

    public aValue[] getAValueValues() {
        return AValue.values();
    }

Tomcat 日志是:

aValue 1
aValue 2
aValue 1
aValue 2
aValue 1
aValue 2
aValue 1
aValue 2
aValue 1
aValue 2
aValue 1
aValue 2
aValue 1
aValue 2
aValue 1
aValue 2
aValue 1
aValue 2
getName 1Value
getName 2Value
getName 3Value
getName 4Value
getAsString 1: 
getAsString 2: 
getAsString 3: 
getAsString 1: 
getAsString 2: 
getAsString 3: 
getAsString 1: 
getAsString 2: 
getAsString 3: 
getAsString 1: 
getAsString 2: 
getAsString 3: 
getAsString 1: 
getAsString 2: 
getAsString 3: 
getAsString 1: 
getAsString 2: 
getAsString 3: 
getAsString 1: 
getAsString 2: 
getAsString 3: 
getAsString 1: 
getAsString 2: 
getAsString 3: 
getAsString 1: 
getAsString 2: 
getAsString 3: 
getName 1Value
getName 2Value
getName 3Value
getName 4Value
getAsString 1: 
getAsString 2: 
getAsString 3: 
getAsString 1: 
getAsString 2: 
getAsString 3: 
getAsString 1: 
getAsString 2: 
getAsString 3: 
getAsString 1: 
getAsString 2: 
getAsString 3: 
getAsString 1: 
getAsString 2: 
getAsString 3: 
getAsString 1: 
getAsString 2: 
getAsString 3: 
getAsString 1: 
getAsString 2: 
getAsString 3: 
getAsString 1: 
getAsString 2: 
getAsString 3: 
getAsString 1: 
getAsString 2: 
getAsString 3: 

当我按下保存按钮时,没有任何反应,也没有任何内容保存到数据库中。看起来它不会进入 getAsObject 方法。我不知道为什么。当我将组件更改为 SelectOneMenu 时,没有问题。但是这个 selectManyCheckBox 东西不起作用。有人有什么主意吗?

4

1 回答 1

2

你的问题在这里:

<p:selectManyCheckbox ... value="#{aView.newObject.aValue}">

您正在将可以获取/设置多个value值的输入组件的属性绑定到表示单个值的属性。这是行不通的。您需要将属性绑定到集合(例如)或数组(例如)属性而不是单个属性。valueList<aValue>aValue[]aValue

例如:

public class NewObject {

    private List<aValue> aValues;

    // ...
}

<p:selectManyCheckbox ... value="#{aView.newObject.aValues}">

或者,或者:

public class NewObject {

    private aValue[] aValues;

    // ...
}

<p:selectManyCheckbox value="#{aView.newObject.aValues}">

请注意,当您使用数组时,不需要整个转换器。另请参阅omnifaces.GenericEnumConverter展示页面


与具体问题无关,根据Java命名约定,枚举类名应该以大写开头,就像常规类和接口一样,所以aValue枚举类名确实是一个不好的选择。顺便说一句,在 Java 中也不鼓励使用匈牙利符号。


更新:为了证明它的工作,这里有一个 SSCCE。

枚举:

public enum Value {

    ONE, TWO, THREE;

    public String getName() {
        return name().toLowerCase();
    }

}

实体:

public class Entity {

    private Value[] values;

    public Value[] getValues() {
        return values;
    }

    public void setValues(Value[] values) {
        this.values = values;
    }

}

托管bean:

@ManagedBean
@RequestScoped // Note: @ViewScoped works as well on this SSCCE.
public class Bean {

    private Entity entity;

    @PostConstruct
    public void init() {
        entity = new Entity();
    }

    public void submit() {
        System.out.println(Arrays.toString(entity.getValues()));
    }

    public Entity getEntity() {
        return entity;
    }

    public Value[] getAvailableValues() {
        return Value.values();
    }

}

视图(没有任何转换器!):

<h:form>
    <p:selectManyCheckbox value="#{bean.entity.values}">
        <f:selectItems value="#{bean.availableValues}" var="value"
            itemValue="#{value}" itemLabel="#{value.name}" />
    </p:selectManyCheckbox> 
    <p:commandButton value="Submit" action="#{bean.submit}" /> 
</h:form>

它对我来说很好用(Mojarra 2.1.28 + PrimeFaces 4.0,但应该适用于所有旧版本,而且这个构造以前不知道有任何错误)。

于 2014-04-16T08:58:51.450 回答