2011-12-18 10 views
16

mam Map z kluczem/wartości, które zainicjować w @PostConstruct następująco:ui: repeat nie działa z mapą

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

Kiedy próbuję iteracyjne nad tą mapą z <ui:repeat> jak pokazano poniżej, i ustawić punkt przerwania na getter dla mapy, zauważam, że nie nazywa się zaczyna, a więc nic nie jest wydrukowane:

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

Ale przy wymianie wyżej kod z <c:foreach>, wszystko działa bez zarzutu, a lista jest drukowany zgodnie z oczekiwaniami, wszelkie pomysły, dlaczego Dostaję takie zachowanie?

Odpowiedz

27

Niestety, UIData i UIRepeat nie mają wsparcia dla iteracji nad mapą w JSF.

Jeśli to Ci przeszkadza (myślę, że to robi), proszę głosować na następującej kwestii i jeśli to możliwe, komentarz, który wyjaśnia zostawić, jak się czujesz na ten temat:

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

w tym czasie, to można iteracyjne nad mapą z jakiegoś małego pomocnika kodu:

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

Następnie zdefiniować funkcję EL w pliku *-taglib.xml jak ten:

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

I wreszcie używać go na Facelet tak:

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

    <ui:repeat value="#{util:mapToList(someDate)}" var="entry" > 
     Key = #{entry.key} Value = #{entry.value} <br/> 
    </ui:repeat> 
+0

@Arjan Tijms, dzięki za wielką odpowiedzi, BTW , jak mogę zagłosować na ten problem? –

+0

Załóż konto i zaloguj się (jest to szybkie i łatwe), a następnie po lewej stronie strony, poniżej "operacji" znajduje się link "Głosowanie" gdzieś na środku listy linków. –

+0

trochę więcej informacji na temat tworzenia nowego pliku taglib. –

9

z el 2.2 Wsparcie można iteracyjne map jak poniżej.

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

Jest to bardzo nieefektywne, ponieważ pełne przeszukiwanie mapy dzieje się ponownie podczas każdego 'get (x)'. Lepiej iterować przez 'entrySet()'. – BalusC

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

również skorzystać z <ui:repeat>

+0

Działa jak urok. Primefaces 6.x JSF 2.2 z p: powtórz Dzięki. –

13

wydaje się działać dla mnie na JSF 1.2, mam nadzieję, że ktoś pomoże ...

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

miło, to działa dla mnie w JSF 2.1 – Kuku

+0

Działa dobrze z mapą '# {sessionScope}'. –

+0

Ta odpowiedź może nie mieć wielu przebojów, ale jest to zdecydowanie moja ulubiona i ta, która w końcu doprowadziła mnie do pracy – Calabacin

Powiązane problemy