【问题标题】:ui:repeat doesn't work with Mapui:repeat 不适用于地图
【发布时间】:2012-01-23 01:55:08
【问题描述】:

我有一个 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;
}

当我尝试使用&lt;ui:repeat&gt; 迭代此 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>

但是当用&lt;c:foreach&gt; 替换上面的代码时,一切正常,并且列表按预期打印,任何想法为什么我会出现这种行为?

【问题讨论】:

    标签: jsf jsf-2 icefaces icefaces-2


    【解决方案1】:

    更新: JSF 2.3(自 2017 年起)支持此 out of the box

    很遗憾,UIDataUIRepeat 不支持在 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;
    }
    

    然后在 *-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>
    

    最后像这样在 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>
    

    【讨论】:

    • @Arjan Tijms,感谢您的出色回答,顺便说一句,我该如何为这个问题投票?
    • 创建一个帐户并登录(快速简便),然后在页面左侧,“操作”下方的链接列表中间某处有一个“投票”链接。
    • 请提供有关创建新标签库文件的更多信息。
    • @Msaleh 我认为最好创建一个关于如何创建 EL 函数的新问题。在 SO 上,将问题尽可能集中在一个主题上是常态。
    • 嗨@ArjanTijms,我认为提一下这在JSF 2 的早期阶段是不可能实现的可能是个好主意,但现在它实际上是可能的。只为新手。
    【解决方案2】:

    似乎在 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>
    

    【讨论】:

    • 适用于#{sessionScope} 地图。
    • 这个答案可能没有多少赞成票,但它是迄今为止我最喜欢的,也是最终让我工作的答案
    【解决方案3】:
    <a4j:repeat value="#{myBean.myMap.entrySet().toArray()}" var="_entry">
            <h:outputText value="#{_entry.key}"/><br/>
            <h:outputText value="#{_entry.value}"/>
    </a4j:repeat>
    

    也可以与&lt;ui:repeat&gt;一起使用

    【讨论】:

    • 像魅力一样工作。 Primefaces 6.x JSF 2.2 和 p:repeat 谢谢。
    • 这确实有效,但 IDE 抱怨 _entry.key 和 _entry.value 无法解析。有人知道如何解决这个问题吗?
    【解决方案4】:

    有了 el 2.2 支持,您可以像下面那样迭代地图。

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

    【讨论】:

    • 这是非常低效的,因为在每个get(x) 期间都会再次进行完整的地图查找。更好地迭代entrySet()
    猜你喜欢
    • 2011-12-30
    • 2012-07-16
    • 2014-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多