这可以通过 EL 3.0 流 API 实现。我最初的尝试是:
<h:panelGroup rendered="#{component.children.stream().filter(c -> c.rendered).count() gt 1}">
<h:outputText value="title" />
<h:panelGroup rendered="#{false}">item1</h:panelGroup>
<h:panelGroup rendered="#{false}">item2</h:panelGroup>
<h:panelGroup rendered="#{false}">item3</h:panelGroup>
</h:panelGroup>
然而,这并没有很好地工作。它意外地陷入了一个无限循环,最终以OutOfMemoryError
. 在查询属性时,EL 变量似乎#{component}
仍然代表前一个组件。rendered
这有点像鸡蛋问题:#{component}
for current 组件仅在其rendered
属性评估时才被注入true
。
鉴于此,我可以看到另外两个选项:通过 ID 显式查找组件,如下所示,
<h:panelGroup id="foo" rendered="#{component.findComponent('foo').children.stream().filter(c -> c.rendered).count() gt 1}">
<h:outputText value="title" />
<h:panelGroup rendered="#{false}">item1</h:panelGroup>
<h:panelGroup rendered="#{false}">item2</h:panelGroup>
<h:panelGroup rendered="#{false}">item3</h:panelGroup>
</h:panelGroup>
或者让它打印一些 CSS 类,这些类依次执行display:none;
.
<h:panelGroup styleClass="#{component.children.stream().filter(c -> c.rendered).count() gt 1 ? 'show' : 'hide'}">
<h:outputText value="title" />
<h:panelGroup rendered="#{false}">item1</h:panelGroup>
<h:panelGroup rendered="#{false}">item2</h:panelGroup>
<h:panelGroup rendered="#{false}">item3</h:panelGroup>
</h:panelGroup>