【问题标题】:How to iterate a HashMap with primefaces selectable datatable如何使用primefaces可选数据表迭代HashMap
【发布时间】:2014-11-23 14:09:12
【问题描述】:

我尝试了不同的解决方案,但没有一个适合我的情况。我希望这个数据表中的所有行都是可选的。问题似乎是<ui:repeat可能覆盖了对象...

我的豆子:

@ManagedBean
@ViewScoped
public class Chat {

    private static Map<String, List<ChatObject>> chat = new LinkedHashMap<String, List<ChatObject>>();
    private ChatObject selectedChatObject;

    public void onChatRowSelection(){
        if(getSelectedChatObject() != null){
            System.out.println("test");
        }
    }

    public List<Map.Entry<String, List<ChatObject>>> getChatList() {
        Set<Map.Entry<String, List<ChatObject>>> productSet = chat.entrySet();
        return new ArrayList<Map.Entry<String, List<ChatObject>>>(productSet);
    }

    @PostConstruct
    public void postConstructMethod() { 

        if(chat.isEmpty()){

            List<ChatObject> objectsList1 = new ArrayList<ChatObject>();
            objectsList1.add(new ChatObject("3369818", "1", "1"));
            objectsList1.add(new ChatObject("3369819", "2", "2"));
            objectsList1.add(new ChatObject("3369820", "3", "3"));

            chat.put("Chat Topic 1", objectsList1);

            List<ChatObject> objectsList2 = new ArrayList<ChatObject>();        
            objectsList2.add(new ChatObject("3369813", "4", "4"));
            objectsList2.add(new ChatObject("3369815", "5", "5"));
            chat.put("Chat Topic 2", objectsList2);
        }

    }

    public ChatObject getSelectedChatObject() {
        return selectedChatObject;
    }

    public void setSelectedChatObject(ChatObject selectedChatObject) {
        this.selectedChatObject = selectedChatObject;
    }
}

我的 JSF:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:p="http://primefaces.org/ui"
    xmlns:fn="http://java.sun.com/jsp/jstl/functions">

<h:form id="form" enctype="multipart/form-data" acceptcharset="ISO-8859-1">

<ui:repeat value="#{chat.chatList}" var="chatEntry">

    <h2><h:outputText value="#{chatEntry.key}" /></h2>
    <br />

    <p:dataTable 
        value="#{chatEntry.value}" 
        var="chatEntryVar"
        widgetVar="chatTableWV" 
        styleClass="geralBorderless"
        style="cursor:pointer" 
        rowKey="#{chatEntryVar.id}" 
        rendered="true"
        selectionMode="single" 
        selection="#{chat.selectedChatObject}"
        paginatorAlwaysVisible="false">

        <p:ajax event="rowSelect"
            listener="#{chat.onChatRowSelection}" 
            oncomplete="chatTableWV.unselectAllRows();">

        </p:ajax>

        <p:column>
            <h:outputText value="#{chatEntryVar.name}" />
        </p:column>
    </p:dataTable>

</ui:repeat>
</h:form>
</html>

我的地图中的所有 5 个ChatObject 都已成功显示在我的页面中。但是onChatRowSelection 方法仅在我单击与我添加到地图中的 second 列表相关的行时打印“test”:objectList2当我点击我添加的第一个列表中的行时 objectList1,当系统进入onChatRowSelection方法时,selectedChatObject将为空。我该如何解决这个问题?

【问题讨论】:

    标签: jsf-2 primefaces datatable facelets uirepeat


    【解决方案1】:

    你的问题在这里:

    <ui:repeat ...>
        <p:dataTable ... widgetVar="chatTableWV">
           <p:ajax ... oncomplete="chatTableWV.unselectAllRows();">
    

    多个数据表在 JavaScript 范围内被分配了完全相同的 widgetVar 名称。实际上,会生成以下 JavaScript 代码:

    window['chatTableWV'] = new Widget(tableElement1);
    window['chatTableWV'] = new Widget(tableElement2);
    window['chatTableWV'] = new Widget(tableElement3);
    // ...
    

    基本上,每次迭代都会覆盖分配给声明的widgetVar 名称的最后一个对象,直到它最终引用最后一个。最后一个所期望的所有小部件基本上都不可用,导致它们在行选择方面不再起作用。

    通过给每个人一个唯一的widgetVar 来相应地修复它。您可以为此使用 &lt;ui:repeat&gt; 的迭代索引。

    <ui:repeat ... varStatus="loop">
        <p:dataTable ... widgetVar="chatTableWV_#{loop.index}">
           <p:ajax ... oncomplete="chatTableWV_#{loop.index}.unselectAllRows();">
    

    这样会生成以下 JavaScript 代码:

    window['chatTableWV_0'] = new Widget(tableElement1);
    window['chatTableWV_1'] = new Widget(tableElement2);
    window['chatTableWV_2'] = new Widget(tableElement3);
    // ...
    

    最后 PrimeFaces 小部件管理器可以找到它们。

    【讨论】:

    • 谢谢!!!我试图在数据表中放置一个动态 id,但这是不可能的.. 从来没有想过 widgetVar。今晚我会测试它!
    猜你喜欢
    • 1970-01-01
    • 2014-11-08
    • 2013-01-14
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    • 1970-01-01
    • 2020-11-18
    • 1970-01-01
    相关资源
    最近更新 更多