2

我正在使用Primefaces 的SelectMany 复选框,并且在将值存储在 Bean 中时遇到了一些麻烦。

我需要一组 SelectManyCheck 框。这是到目前为止的xhtml,

<c:set var="obj" value="#{userBean.userSettingsMap}"> </c:set>
<c:forEach items="#{obj}" var="entry">
  <h:outputText value="#{entry.key} " /><!--Correctly prints the key -->
  <p:selectManyCheckbox value="#{entry.value}"><!-- `entry.value` SHOULD correspond to inner lists --->
    <!-- I want values of these check boxes to be updated in my ManagedBean's property -->
    <f:selectItem itemLabel="Option 1" itemValue="Option 1" />
    <f:selectItem itemLabel="Option 2" itemValue="Option 2" />
    <f:selectItem itemLabel="Option 3" itemValue="Option 3" />
</p:selectManyCheckbox>
</c:forEach>   

Select Many 复选框的数组呈现在页面上。但是当我提交页面时,子列表没有更新。而是我的 ManagedBean 中的对象没有得到更新。

因此,在提交时,我会在对话框中显示空白列表。

{键 1=[],键 2=[]}

在我的 ManagedBean 中,

  private Map<String,List<String>> userSettingsMap; 

子列表将对应于 <p:selectManyCheckbox>视图上的每个

提交按钮与示例中的相同。

  <p:commandButton value="Submit" update="display" oncomplete="dlg.show()" />
    <p:dialog header="Selected Values" modal="true" showEffect="fade" hideEffect="fade" widgetVar="dlg">

      <p:outputPanel id="display">
          <p:dataList value="#{userService.userMaintainceMap}" var="option">
              #{option}
          </p:dataList>             
      </p:outputPanel>
4

1 回答 1

3

您使用 JSTL 对 Map 进行迭代c:forEach,这意味着每个条目都将是最有可能实现的内部迭代器类型Map.Entry(例如MappedValueExpression.Entry)。这里有一个setValue方法,但它不符合 JavaBeans 约定,这意味着 EL 不会找到它。

结果#{entry.value}将被视为只读属性<p:selectManyCheckbox>无法将其值存储在那里。我希望会出现一个例外,但也许它在某个地方被吞没了。一个普通的表单和一个普通的命令按钮肯定会在这里触发异常。

第二个问题是您有一个带有泛型的 Map 作为您选择的目标,但是 EL 将无法看到这些泛型(归咎于 Java 中臭名昭著的缺乏具体化的泛型),因此特别看不到该值是列表。然后它将String[]在您的地图中放置一个实例。

如果您使用按其键索引的 Map 表达式作为选择的目标并声明要键入的 Map String[],您的代码应该可以工作。

例如

内部复选框.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:p="http://primefaces.org/ui">

    <h:body>

        <h:form>
            <c:forEach items="#{innerCheckboxBacking.userSettingsMap}" var="entry">
                <h:outputText value="#{entry.key}" />
                <p:selectManyCheckbox value="#{innerCheckboxBacking.userSettingsMap[entry.key]}">
                    <f:selectItem itemLabel="Option 1" itemValue="Option 1" />
                    <f:selectItem itemLabel="Option 2" itemValue="Option 2" />
                    <f:selectItem itemLabel="Option 3" itemValue="Option 3" />
                </p:selectManyCheckbox>
            </c:forEach>

            <h:commandButton value="Submit" action="#{innerCheckboxBacking.action}" />

        </h:form>

    </h:body>
</html>

InnerCheckboxBacking.java:

@ManagedBean
@ViewScoped
public class InnerCheckboxBacking {

    private Map<String, String[]> userSettingsMap = new LinkedHashMap<>();

    @PostConstruct
    public void init() {
        userSettingsMap.put("key1", null);
        userSettingsMap.put("key2", null);
    }

    public void action() {
        String[] result = userSettingsMap.get("key1");
        for (String string : result) {
            System.out.println(string);
        }
    }

    public Map<String, String[]> getUserSettingsMap() {
        return userSettingsMap;
    }

}
于 2012-09-29T11:23:45.823 回答