如何仅在呈现至少两个 children 时才呈现 JSF 组件(标题 + 项目)?

How to render a JSF component only if at least two children are rendered (title + item)?

我有一个:

<h:panelGroup />
  <h:outputText value="title" />
  <h:itemThatSometimesWillShow rendered="sometimes1" />
  <h:itemThatSometimesWillShow rendered="sometimes2" />
  <h:itemThatSometimesWillShow rendered="sometimes3" />
  ...many more

而且我希望,如果 itemThatSometimesWillShow 的 none 显示,整个面板(实际上是标题)也不显示。

我确实尝试使用复合组件的 #{cc.childCount} > 1,但我不在复合实现中,所以看起来它总是 return 0.

有什么想法吗? (我正在搜索带有 js 或 EL 的内容以用于 parent 面板组的 rendered 属性)

我很快就会接受这个:

<h:panelGroup rendered="{bean.isSometimes()}"/>
  <h:outputText value="title" />
  <h:itemThatSometimesWillShow rended="{bean.isSometimes1()}" />
  <h:itemThatSometimesWillShow rended="{bean.isSometimes2()}" />
  <h:itemThatSometimesWillShow rended="{bean.isSometimes3()}" />

在 bean 中:

public boolean isSometimes()
{
    return isSometimes1() || isSometimes2() || isSometimes3();
}

这可以通过 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 结束的无限循环。在查询 rendered 属性时,#{component} EL 变量似乎仍然代表前一个组件。这是一个先有鸡还是先有蛋的问题:当前组件的 #{component} 仅在其 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 class 进而执行 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>