映射到f:selectInes for h:selectOneMenu中断f:ajax

时间:2017-04-28 11:29:43

标签: jsf

当h:selectOneMenu中的f:selectItems标记获得一个Set时,f:ajax标记起作用,此后h:outputText将使用所选值进行更新。但是当f:selectItems标签收到Map时,f:ajax似乎不再做任何事了。我已经为演示创建了一个最小的例子。

在第一个剪切f的值:selectItems产生一个Set,一切都按预期工作:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
  <h:head>
    <title>SET</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  </h:head>
  <h:body>
    <h:form>
      <h:selectOneMenu value="#{setVsMap.string}">
        <f:selectItems value="#{setVsMap.strings}"/>
        <f:ajax render="someId"/>
      </h:selectOneMenu>
    </h:form>
    <div>
      <h:outputText value="String: "/>
      <h:outputText id="someId" value="#{setVsMap.string}"/>
    </div>
  </h:body>
</html>

在第二个(几乎相同的)片段中,f:selectItems值产生一个映射。而这次h:outputText(带有'someId')不会呈现:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
  <h:head>
    <title>MAP</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  </h:head>
  <h:body>
    <h:form>
      <h:selectOneMenu value="#{setVsMap.date}">
        <f:selectItems value="#{setVsMap.dates}"/>
        <f:ajax render="someId"/>
      </h:selectOneMenu>
    </h:form>
    <div>
      <h:outputText value="Date: "/>
      <h:outputText id="someId" value="#{setVsMap.date}"/>
    </div>
  </h:body>
</html>

这是两个页面的支持bean:

@Named
@ViewScoped
public class SetVsMap implements Serializable {

  private String string; // getter and setter omitted
  private Date date; // getter and setter omitted
  private Set<String> strings;
  private Map<String, Date> dates;

  @PostConstruct
  public void init() {
    strings = new LinkedHashSet<>();
    strings.add("foo");
    strings.add("bar");
    strings.add("baz");

    dates = new LinkedHashMap<>();
    Calendar c = Calendar.getInstance();
    c.add(Calendar.DATE, -1);
    dates.put("Yesterday", c.getTime());
    c.add(Calendar.DATE, 1);
    dates.put("Today", c.getTime());
    c.add(Calendar.DATE, 1);
    dates.put("Tomorrow", c.getTime());
  }

  public Set<String> getStrings() {
    return strings;
  }

  public Map<String, Date> getDates() {
    return dates;
  }
}

调试显示调用了setString方法,而从不调用setDate方法。

这是为什么?如何解决?

使用mojarra 2.2.13在glassfish 4.1.2上进行测试。

1 个答案:

答案 0 :(得分:0)

您可以为Date类型实现自己的转换器以显示其String值或使用f:convertDateTime标记,即:

<h:selectOneMenu value="#{setVsMap.string}">
    <f:selectItems value="#{setVsMap.strings}"/>
    <f:convertDateTime pattern="d-M-yyyy" />
    <f:ajax render="someId"/>
</h:selectOneMenu>

<h:outputText id="someId" value="#{setVsMap.date}" >
    <f:convertDateTime pattern="d-M-yyyy" />
</h:outputText>