2015-09-04 76 views
3

我有一個Home。每個Home都有一個列表Room s。每個Room有零個或多個Person s。在Facelets中使用EL變量<c:set><ui:repeat>標籤

我想統計每個家庭的總人數。但是我不能添加一個新變量來記錄任何後臺bean或實體中的人員數量。所以我只想通過<c:set>在視圖中進行計數。

我第一次嘗試這樣的:

<c:set var="personCount" value="${0}" /> 
<ui:repeat var="home" value="#{mybackingBean.homes}"> 
    <ui:repeat var="room" value="#{home.rooms}"> 
     ${personCount += room.persons.size()} 
    </ui:repeat> 
    <h:panelGrid columns="2"> 
     <h:outputLabel value="#{home.id}" /> 
     <h:outputLabel value="#{personCount}" /> 
    </h:panelGrid> 
</ui:repeat> 

我怎樣才能實現呢?

回答

4

有幾個錯誤。


首先,

${personCount += room.persons.size()} 

在EL中,+=string concatenation operator。所以,這會給你基本上String.valueOf(personCount) + String.valueOf(size)的結果。如果計數初始化爲0並且有3個人,則將打印03

您基本上想要將personCount + size的結果重新分配回變量personCount。您需要使用<c:set>重新設置變量,如下所示。

<c:set var="personCount" value="${personCount + room.persons.size()}" /> 

其次,

<c:set var="personCount" value="${0}" /> 
<[for each home]> 
    <[for each room]> 
     <c:set var="personCount" value="${personCount + room.persons.size()}" /> 

personCount該被初始化爲0兩者的迭代之外。所以,對於每個家庭來說,你也可以通過這種方式來計算以前所有家庭的人數。你想在第一次迭代中聲明它。

<[for each home]> 
    <c:set var="personCount" value="${0}" /> 
     <[for each room]> 
      <c:set var="personCount" value="${personCount + room.persons.size()}" /> 

這不是EL相關。這只是一個邏輯錯誤,它也會導致「普通香草」Java中出現同樣的問題。


第三,

JSTL標記等(從XHTML模板來JSF組件樹轉換期間)期間視圖編譯時間<c:set>運行。 JSF組件(如<ui:repeat>)在視圖呈現時(在從JSF組件樹轉換爲HTML輸出期間)運行。因此,<c:set><ui:repeat>迭代期間不運行。因此,它看不到迭代變量var。您基本上也需要在查看構建時間內迭代。您可以使用JSTL <c:forEach>

所以,一切的一切,你intented的解決方案是這樣的:

<c:forEach items="#{bean.homes}" var="home"> 
    <c:set var="personCount" value="${0}" /> 
    <c:forEach items="#{home.rooms}" var="room"> 
     <c:set var="personCount" value="${personCount + room.persons.size()}" /> 
    </c:forEach> 

    <h:panelGrid columns="2"> 
     <h:outputLabel value="#{home.id}" /> 
     <h:outputLabel value="#{personCount}" /> 
    </h:panelGrid> 
</c:forEach> 

有關深入的解釋,另見JSTL in JSF2 Facelets... makes sense?


然而,隨着+=運營商顯然不會在您的情況下會導致EL異常,這意味着您已經在使用EL 3.0。這反過來意味着你可以使用新的EL 3.0 lambda and stream features

<ui:repeat value="#{bean.homes}" var="home"> 
    <h:panelGrid columns="2"> 
     <h:outputLabel value="#{home.id}" /> 
     <h:outputLabel value="#{home.rooms.stream().map(room -> room.persons.size()).sum()}" /> 
    </h:panelGrid> 
</ui:repeat> 

不再需要計數循環。不,這不需要Java 8,它可以在Java 7上工作。

相關問題