it-swarm-pt.tech

ui: repeat não funciona com o Map

Eu tenho um Map de key/values, que inicializo em @PostConstruct do seguinte modo:

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;
}

Quando tento percorrer este mapa com <ui:repeat> como mostrado abaixo, e eu defino um ponto de interrupção no getter para o Mapa, noto que ele não está sendo chamado e, portanto, nada é impresso:

<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>

Mas ao substituir o código acima por <c:foreach>, tudo funciona bem, e a lista é impressa conforme o esperado, alguma idéia de por que estou tendo esse comportamento?

23
Mahmoud Saleh

ATUALIZAÇÃO: O JSF 2.3 (desde 2017) suporta isso fora da caixa .

Infelizmente, UIData e UIRepeat não têm suporte para iterar sobre um mapa no JSF.

Se isso o incomoda (acho que sim), vote no seguinte problema e, se possível, deixe um comentário que explique como você se sente sobre isso:

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

Enquanto isso, você pode percorrer um mapa com algum código auxiliar:

/**
 * 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;
}

Em seguida, defina uma função EL em um *-taglib.xml arquivo como este:

<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>

E, finalmente, use-o em um Facelet como este:

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

    <ui:repeat value="#{util:mapToList(someDate)}" var="entry" >
        Key = #{entry.key} Value = #{entry.value} <br/>
    </ui:repeat>
34
Arjan Tijms
<a4j:repeat value="#{myBean.myMap.entrySet().toArray()}" var="_entry">
        <h:outputText value="#{_entry.key}"/><br/>
        <h:outputText value="#{_entry.value}"/>
</a4j:repeat>

também use com <ui:repeat>

24
user1483443

Parece trabalhar para mim no JSF 1.2, espero que ajude alguém ...

    <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>
21
c30

com o suporte ao 2.2, você pode iterar mapas como abaixo.

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