JSF 在一个数据表中显示两个列表

JSF Display two lists in one datatable

所以我有 2 个列表,其中一个来自数据库,第二个列表稍后用传递的名称更新。当用户显示页面时,第一个列表是在@PostConstruct 方法上获取的,第二个列表是为 etiquette.

中的每个 name 值更新的

showClients.java 具有 @ViewScoped 值的 bean

     private List<Etiquette> etiquetteList;
     private List<Client> clientList;

    ...getters and setters 

       @PostConstruct
        public void init() {
            HttpSession session = SessionUtil.getSession();
            User user = (User) session.getAttribute("user");
            etiquetteList = etiquetteDAO.getAllEtiquettes(user);
            System.out.println(etiquetteList);
        }

        public List<Client> showClientsForEtiquette(String etiquetteName) {
            clientList = clientDAO.findClientsByEtiquetteName(etiquetteName);
            System.out.println(clientList);
            return clientList;
        }

目前一切正常。我 etiquetteListclientList 都装满了数据。自从我开始使用这些数据进行调试以来,我就这样做了

<h:form>
    <ui:repeat value="#{showClients.etiquetteList}" var="etiquette">
                        <p:panel id="horizontal" header="#{etiquette.name}" toggleSpeed="100" toggleable="true" toggleOrientation="vertical" collapsed="true" >  
                            <p:panelGrid columns="3" layout="grid" styleClass="showcase-text-align-center" >
                                <h:outputText value="Client name"/>
                                <h:outputText value="Client email"/>
                                <h:outputText value="Show details"/>
                            </p:panelGrid>
                            <p:panelGrid id="clientData" styleClass="showcase-text-align-center">
                                <ui:repeat value="#{showClients.clientList}" var="client">
                                    <p:panelGrid columns="3" layout="grid" styleClass="showcase-text-align-center" >
                                        <h:outputText value="#{client.name}"/>
                                        <h:outputText value="#{client.email}"/>
                                        <p:commandButton value="details" type="button" onclick="PF('clientDetails').show();" >
                                            <f:param name="client" value="client"/>
                                        </p:commandButton>
                                    </p:panelGrid>
                                </ui:repeat>
                            </p:panelGrid>
                        </p:panel>   
                    </ui:repeat>
    </h:form>

但这种方式很笨拙,我想以非常不同的方式显示这些数据。我想使用 PrimeFaces 库在 dataTable 中显示它 - 我想要可切换的功能(可切换的方式是您只需单击礼仪名称和 show/hide 客户信息) ,分页,延迟获取等。据我尝试实现,我已经做到了。

        <h:form id="groupForm">
                        <h:form>
                        <p:dataTable value="#{showClients.etiquetteList}" var="e" sortBy="#{e.name}" expandedRow="false"  expandableRowGroups="true"  rows="10"
                                     paginator="true"
                                     paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                                     currentPageReportTemplate="{startRecord}-{endRecord} of {totalRecords} records"
                                     rowsPerPageTemplate="5,10,15" >
                            <p:headerRow>
                                <f:facet name="header">
                                <p:column colspan="3">
                                    <h:outputLabel value="#{e.name}" />
                                </p:column>
                                </f:facet>
                            </p:headerRow>
                            <p:column colspan="3" style="margin: 20px 0;" >
                                <p:dataTable value="#{showClients.showClientsForEtiquette(e.name)}" var="c" lazy="true" expandedRow="false">
                                    <p:column headerText="Email">
                                        #{c.email}
                                    </p:column>
                                    <p:column headerText="Szczegóły">
                                        <p:commandButton value="Szczegóły"/>
                                    </p:column>
                                    <p:column  headerText="Usuń" >
                                        <p:commandButton value="Usuń"/>
                                    </p:column>
                                </p:dataTable>
                            </p:column>

                        </p:dataTable>
                    </h:form>

这就是我想要显示数据的方式。我该如何处理?我读到你不能设置 table 的 header,因为 table 是逐行生成的,数据还没有显示为 header。有什么解决方法吗?另外,如何使我的 table 行(这一行带有 e.name )可以切换?在dataTable里面用一些panelGrid

+----------------------------------------------------+
|                      e.name (value)                | 
+-----------------------------------------------------
| Email (string) | Detail (string) | Delete (string) |
|     c.email    |      button     |     button      |
<h:form id="groupsForm">

            <p:dataTable value="#{showClients.etiquetteList}" var="e">
                <p:column>
                    <f:facet name="header">Some header</f:facet>
    <p:growl id="msgs" showDetail="true" skipDetailIfEqualsSummary="true" />
                    <p:panel id="toggleable" header="#{e.name}" toggleable="true" toggleSpeed="500" style="margin: 20px 0;">
                        <p:ajax event="close" listener="#{showClients.onClose}" update="msgs"/>
                        <p:ajax event="toggle" listener="#{showClients.onToggle}" update="msgs"/>
                        <p:repeat value="#{e.clientCollection}" var="c" >
                            <p:panelGrid columns="3" >
                                <p:column headerText="Email">
                                    #{c.email}
                                </p:column>
                                <p:column headerText="Detail">
                                    <p:commandButton value="Detail"/>
                                </p:column>
                                <p:column headerText="Delete">
                                    <p:commandButton value="Delete"/>
                                </p:column>
                            </p:panelGrid>
                        </p:repeat>
                    </p:panel>

                </p:column>
            </p:dataTable>
        </h:form>

我已经发布了答案,但在与@Kukeltje 的评论部分讨论后,我决定更改一些内容。所以这是一个代码。

<h:form id="groupsForm">
            <p:dataTable value="#{showClients.etiquetteList}" 
                         var="e" 
                         style="width: 80%; margin:0 auto;" 
                         paginator="true" 
                         rows="5" 
                         rowsPerPageTemplate="5,10,15,20,50" 
                         lazy="true" 
                         paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                         currentPageReportTemplate="{startRecord}-{endRecord} of {totalRecords} records">
                <p:column>
                    <p:growl id="msgs" showDetail="true" skipDetailIfEqualsSummary="true" />
                    <f:facet name="header">General header</f:facet>                    
                    <p:panel id="toggleable" header="#{e.name}" toggleable="true" toggleSpeed="500" collapsed="true" style="margin: 5px 0; border: 0;">
                        <p:ajax event="toggle" listener="#{showClients.onToggle}" update="msgs"/>
                        <p:panel toggleable="true" header="Client" toggleSpeed="500" collapsed="true" style="margin: 5px 0; border: 0;">                            
                            <p:dataTable value="#{e.clientCollection}" 
                                         var="c" 
                                         lazy="true" 
                                         paginator="true" 
                                         rows="5" 
                                         rowsPerPageTemplate="5,10,15,20,50"                                         
                                         paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                                         currentPageReportTemplate="{startRecord}-{endRecord} of {totalRecords} records"
                                         reflow="true"
                                         >
                                <p:column>
                                    <p:panelGrid columns="4" style="margin: 5px 0; border: 0;">   
                                        <p:column headerText="Name" priority="1">
                                            #{c.name}
                                        </p:column>
                                        <p:column headerText="Email" priority="1">
                                            #{c.email}
                                        </p:column>
                                        <p:column headerText="Email" priority="2">
                                            <p:commandButton value="Details"/>
                                        </p:column>
                                        <p:column headerText="Email" priority="3">
                                            <p:commandButton value="Delete"/>
                                        </p:column>
                                    </p:panelGrid>
                                </p:column>
                            </p:dataTable>
                        </p:panel>
                    </p:panel>
                </p:column>
            </p:dataTable>
        </h:form>

我正在使用 PrimeFaces library。那么与您的代码相比有什么变化。首先,我摆脱了 headerRow 元素并将其替换为 <p:panel> 这样您可以更轻松地设置面板的 header 也将是 toggleable .在 facet 元素中,我设置了通用名称 table - 它是 header。接下来我们有另一个 <p:panel> - 我们有 2 个面板的原因是您可以先打开,然后再打开包含客户列表的第二个。所以现在我们有嵌套数据table。 <p:dataTable> table 都用于从列表中获取数据。使用分页和滚动等非常容易,您只需将新参数添加到 dataTable 属性即可。每个 dataTable 都必须有 <p:column> 来显示数据,所以我们用它来包装 <p:panelGrid> 我们的页面布局。就 <p:ajax> 而言。每当我们切换第一个面板时,我们都用它来显示一些弹出消息。在您的 bean 中,您应该有一个使用 FacesMessage 更新值的方法,甚至作为参数传递给 ajax。
showClients.java toggle method

    public void onToggle(ToggleEvent event) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, event.getComponent().getId() + " toggled", "Status:" + event.getVisibility().name());
        FacesContext.getCurrentInstance().addMessage("groupsForm:msgs", message);
    }