【问题标题】:How to render a JSF component only if at least two children are rendered (title + item)?仅当至少呈现两个子项(标题+项目)时,如何呈现 JSF 组件?
【发布时间】:2016-10-03 23:30:29
【问题描述】:

我有一个:

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

我希望这样,如果 itemThatSometimesWillShow 没有显示,整个面板(实际上是标题)也不会显示。

我确实尝试过使用复合组件的 #{cc.childCount} &gt; 1,但我不在复合实现中,所以看起来它总是会返回 0

有什么想法吗? (我正在寻找带有 js 或 EL 的东西以在父 panelGroup 的 rendered 属性中使用)

【问题讨论】:

    标签: jsf el conditional-rendering


    【解决方案1】:

    这可以通过 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 结束。看来#{component} EL 变量仍然代表在咨询rendered 属性时的前一个组件。这有点像鸡蛋问题:当前组件的 #{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 类,然后它会执行 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>
    

    【讨论】:

    • 太棒了!我在想:难道没有像component.children.size() 这样的方法吗?我去找找……
    • 是的,就是这样,或者#{component.childCount} 更有效。它只是对解决您的特定问题没有帮助,因为它没有参考孩子的rendered 属性。
    【解决方案2】:

    我很快就会这样做:

    <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();
    }
    

    【讨论】:

    • 这就是我现在所做的,谢谢!但是没有更抽象的方式吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-08
    • 2020-10-13
    • 1970-01-01
    • 2017-07-11
    • 2019-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多