使用< c:set>的EL变量;内部Facelets< ui:repeat>标签 [英] Using EL variable of <c:set> inside Facelets <ui:repeat> tags
问题描述
我有一个Home
.每个Home
都有一个Room
的列表.每个Room
具有零个或多个Person
.
I have a Home
. Each Home
has a list of Room
s. Each Room
has zero or more Person
s.
我想计算每个家庭的总人数.但是我无法添加新变量来记录任何支持bean或实体中的人员计数.因此,我只想通过<c:set>
在视图中对其进行计数.
I would like to count total persons of each home. But I can't add a new variable to record person count in any backing beans or entity. So I'd like to count it in the view only via <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>
我该如何实现?
推荐答案
有几个错误.
首先
${personCount += room.persons.size()}
在EL中,+=
是字符串串联运算符.因此,这基本上将为您提供String.valueOf(personCount) + String.valueOf(size)
的结果.如果计数初始化为0
并且有3
个人,则将打印03
.
In EL, the +=
is the string concatenation operator. So, this will give you basically the result of String.valueOf(personCount) + String.valueOf(size)
. If the count is initialized to 0
and there are 3
persons, then this will print 03
.
您基本上想将personCount + size
的结果重新分配回变量personCount
.您需要使用<c:set>
重新设置变量,如下所示.
You basically want to re-assign the result of personCount + size
back to variable personCount
. You need to re-set the variable using <c:set>
as below.
<c:set var="personCount" value="${personCount + room.persons.size()}" />
第二,
Second,
<c:set var="personCount" value="${0}" />
<[for each home]>
<[for each room]>
<c:set var="personCount" value="${personCount + room.persons.size()}" />
在两个迭代之外,都用0
初始化了personCount
.因此,对于每个房屋,您也将以这种方式计算以前所有房屋的人数.您想在第一次迭代中声明它.
The personCount
is initialized with 0
outside both iterations. So, for each home you'll this way count the persons of all previous homes as well. You want to declare it inside the first iteration.
<[for each home]>
<c:set var="personCount" value="${0}" />
<[for each room]>
<c:set var="personCount" value="${personCount + room.persons.size()}" />
这与EL不相关.这只是一个逻辑错误,也会在普通香草" Java中引起同样的问题.
This is not EL related. This is just a logic error which would cause the same problem in "plain vanilla" Java as well.
第三,
JSTL标记在视图构建期间(从XHTML模板转换为JSF组件树期间)运行.诸如<ui:repeat>
之类的JSF组件在视图渲染期间运行(在从JSF组件树到HTML输出的转换过程中).因此,<c:set>
不会在<ui:repeat>
迭代期间运行.因此,它看不到迭代变量var
.基本上,您还需要在视图构建期间进行迭代.您可以为此使用JSTL <c:forEach>
.
JSTL tags like <c:set>
run during view build time (during conversion from XHTML template to JSF component tree). JSF components like <ui:repeat>
run during view render time (during conversion from JSF component tree to HTML output). So, the <c:set>
doesn't run during <ui:repeat>
iteration. Thus, it cannot see the iteration variable var
. You basically need to iterate during view build time as well. You can use JSTL <c:forEach>
for this.
因此,总而言之,您打算使用的解决方案如下所示:
So, all in all, your intented solution look like this:
<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>
有关深入的解释,另请参见 JSF2 Facelets中的JSTL ...很有意义?
For an in depth explanation, see also JSTL in JSF2 Facelets... makes sense?
但是,由于+=
运算符显然不会导致EL异常,这意味着您已经在使用EL 3.0.反过来,这意味着您可以使用新的 EL 3.0 lambda和流功能.
However, as the +=
operator apparently doesn't cause an EL exception in your case, this means that you're already using EL 3.0. This in turn means that you can use the new 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上很好地工作.
No need for a counting loop anymore. No, this does not require Java 8, it works on Java 7 as good.
这篇关于使用< c:set>的EL变量;内部Facelets< ui:repeat>标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!