2011-12-18 17 views
16

Tôi có một Map của khóa/giá trị, mà tôi khởi tạo trong @PostConstruct như sau:ui: lặp lại không làm việc với 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; 
} 

Khi tôi cố gắng để lặp qua Bản đồ này với <ui:repeat> giống như hiển thị dưới đây, và tôi đặt một điểm break trên getter cho Bản đồ, tôi nhận thấy rằng nó không phải là nhận được gọi, và vì vậy không có gì được in:

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

Nhưng khi thay thế trên mã với <c:foreach>, mọi thứ hoạt động tốt, và danh sách được in như mong đợi, bất kỳ ý tưởng nào tại sao Tôi nhận được hành vi như vậy?

Trả lời

27

Thật không may, UIDataUIRepeat không có hỗ trợ cho việc lặp qua bản đồ trong JSF.

Nếu đây phiền bạn (tôi đoán nó), hãy bỏ phiếu cho các vấn đề sau đây và nếu có thể để lại nhận xét rằng giải thích cách bạn cảm nhận về điều này:

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

Trong lúc này, bạn có thể lặp trên một bản đồ với một số mã helper nhỏ:

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

Sau đó xác định một chức năng EL trong một file *-taglib.xml như thế này:

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

Và cuối cùng sử dụng nó trên một Facelet như thế này:

<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, cảm ơn vì câu trả lời tuyệt vời, BTW , làm thế nào tôi có thể bỏ phiếu cho vấn đề này? –

+0

Tạo tài khoản và đăng nhập (thật nhanh chóng và dễ dàng), sau đó ở bên tay trái của trang, bên dưới "hoạt động" có liên kết "bỏ phiếu" ở đâu đó ở giữa danh sách liên kết. –

+0

ít thông tin thêm về việc tạo tệp taglib mới. –

9

với 2.2 hỗ trợ el bạn có thể lặp lại bản đồ như dưới đây.

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

Điều này rất không hiệu quả khi tra cứu toàn bộ bản đồ xảy ra một lần nữa trong mỗi 'get (x)'. Lặp lại tốt hơn trên '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> 

cũng sử dụng với <ui:repeat>

+0

Hoạt động như một sự quyến rũ. Primefaces 6.x JSF 2.2 với p: lặp lại Cảm ơn. –

13

Dường như làm việc cho tôi trên JSF 1.2, hy vọng nó sẽ giúp người ...

<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

đẹp, điều này làm việc cho tôi trong JSF 2.1 – Kuku

+0

Hoạt động tốt với bản đồ '# {sessionScope}'. –

+0

Câu trả lời này có thể không có nhiều upvotes nhưng nó là của xa yêu thích của tôi và là một trong đó cuối cùng đã cho tôi làm việc – Calabacin

Các vấn đề liên quan