ui:repeat不适用于Map

Mah*_*leh 22 jsf icefaces jsf-2 icefaces-2

我有一个Map键/值,我初始化@PostConstruct如下:

Map<String, String> myMap;

@PostConstruct
public void init() {

  myMap=new LinkedHashMap<String, String>();
  myMap.put("myKey","myValue");

}

public Map<String, String> getMyMap() {
    return myMap;
}

public void setMyMap(Map<String, String> myMap) {
    this.myMap = myMap;
}
Run Code Online (Sandbox Code Playgroud)

当我尝试用<ui:repeat>如下所示的迭代迭代这个Map时,我在Map的getter上设置了一个断点,我注意到它没有被调用,所以没有打印出来:

<ice:panelGroup>
    <ui:repeat items="#{myBean.myMap}" var="entry" varStatus="loop">
        <input type="checkbox" name="myCheckBoxes" value="#{entry.value}" />
        <span class="#{fn:contains(entry.value,'g') ? 'bold-style' : ''}">#{entry.key}</span>
    </ui:repeat>
</ice:panelGroup>
Run Code Online (Sandbox Code Playgroud)

但是当替换上面的代码时<c:foreach>,一切正常,并且列表按预期打印,任何想法为什么我会得到这样的行为?

Arj*_*jms 33

更新: JSF 2.3(自2017年起)支持开箱即用.

不幸的是,UIData并且UIRepeat不支持在JSF中迭代地图.

如果这困扰你(我猜它确实如此),请投票支持以下问题,如有可能,请留下评论,解释您对此的看法:

http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-479

与此同时,您可以使用一些小帮助代码迭代Map:

/**
 * Converts a Map to a List filled with its entries. This is needed since 
 * very few if any JSF iteration components are able to iterate over a map.
 */
public static <T, S> List<Map.Entry<T, S>> mapToList(Map<T, S> map) {

    if (map == null) {
        return null;
    }

    List<Map.Entry<T, S>> list = new ArrayList<Map.Entry<T, S>>();
    list.addAll(map.entrySet());

    return list;
}
Run Code Online (Sandbox Code Playgroud)

然后在如下*-taglib.xml文件中定义EL函数:

<namespace>http://example.com/util</namespace> 

<function>
    <function-name>mapToList</function-name>
    <function-class>com.example.SomeClass</function-class>
    <function-signature>java.util.List mapToList(java.util.Map)</function-signature>
</function>
Run Code Online (Sandbox Code Playgroud)

最后在Facelet上使用它,如下所示:

<html xmlns:util="http://example.com/util">

    <ui:repeat value="#{util:mapToList(someDate)}" var="entry" >
        Key = #{entry.key} Value = #{entry.value} <br/>
    </ui:repeat>
Run Code Online (Sandbox Code Playgroud)


小智 24

<a4j:repeat value="#{myBean.myMap.entrySet().toArray()}" var="_entry">
        <h:outputText value="#{_entry.key}"/><br/>
        <h:outputText value="#{_entry.value}"/>
</a4j:repeat>
Run Code Online (Sandbox Code Playgroud)

也用 <ui:repeat>


小智 19

似乎在JSF 1.2上为我工作,希望它可以帮助某人......

    <h:panelGroup>
      <ul>
        <ui:repeat value="#{myBean.myMap.keySet().toArray()}" var="key">
          <li>key:#{key}</li>
          <li>value:#{myBean.myMap[key]}</li>
        </ui:repeat>
      </ul>
    </h:panelGroup>
Run Code Online (Sandbox Code Playgroud)

  • 这个答案可能没有太多赞成票,但它是迄今为止我最喜欢的,也是最终让我工作的答案 (2认同)

小智 10

有了2.2支持,你可以迭代下面的地图.

<ui:repeat value="#{myBean.stats.keySet().toArray()}" var="x">
    <h:outputText value="#{myBean.stats.get(x)}" /><br />
</ui:repeat>
Run Code Online (Sandbox Code Playgroud)

  • 这是非常低效的,因为在每个`get(x)`期间再次发生完整的地图查找.更好地迭代`entrySet()`. (6认同)