【问题标题】:How do I conditionally render an <f:facet>?如何有条件地渲染 <f:facet>?
【发布时间】:2011-05-21 03:01:29
【问题描述】:

我希望能够有条件地从 PrimeFaces 面板元素中省略页脚:

<p:panel header="some text">
    <f:facet name="footer">
        #{message}
    </f:facet>
    <!-- ... -->
</p:panel>

我希望rendered 属性能起作用:

<p:panel header="some text">
    <f:facet name="footer" rendered="#{!empty message}">
        #{message}
    </f:facet>
    <!-- ... -->
</p:panel>

但页脚仍然呈现,内容为空。 facet 似乎没有rendered 属性:http://www.jsftoolbox.com/documentation/help/12-TagReference/core/f_facet.html

正确的做法是什么?

【问题讨论】:

  • 我做了一些测试:没有任何内容的页脚(允许空白)不会被渲染。一个带有 any 内容的页脚,即使它是一个返回 null/empty 的简单 EL,它也会呈现页脚。我不确定需要哪种行为,可能值得在 PF 问题跟踪器上报告:code.google.com/p/primefaces/issues
  • @BalusC:好像是错误报告时间。

标签: jsf jsf-2 primefaces


【解决方案1】:

这是我在尝试有条件地在复合组件中渲染构面时所做的。

<composite:interface>
    <composite:facet name="header" required="false" />
</composite:interface>
<composite:implementation>
    <p:panel>
        <c:if test="#{empty component.facets.header}" >
            <f:facet id="#{cc.attrs.id}_default_header" name="header">
            all sorts of stuff here
            </f:facet>
        </c:if>
        <c:if test="#{not empty component.facets.header}">
            <composite:insertFacet id="#{cc.attrs.id}_custom_header" name="header" />
        </c:if>
        <composite:insertChildren id="#{cc.attrs.id}_content"/>
    </p:panel>
</composite:implementation>

这让复合组件的用户在需要时提供标题方面,如果他们不提供,我们提供默认值。显然,您不能提供默认值,而不能做任何事情。

这在 jsf 控件中混合了 c:if,但我们没有看到任何不利影响。

【讨论】:

  • 有趣。我想到了这一点,但由于我没有测试它的环境,我担心在那里混合c:if 不会像预期的那样运行。让我们看看它是否适用于 OP 的情况。 :)
  • 这对我不起作用。 @Bozho:见上一句。我认为问题正如@BalusC 在他对我的问题的评论中所描述的那样。
  • 好奇你所说的“对我不起作用”是什么意思,因为我们已经在生产环境中运行了几个月的代码。
  • 我的意思是:&lt;c:if test="#{!empty message}"&gt;&lt;f:facet name="footer"&gt;#{message}&lt;/f:facet&gt;&lt;/c:if&gt; 没有在#{message} 为空时省略页脚。我不是在编写复合组件,所以这可能是问题的一部分。
  • 它确实只在复合组件或标签文件中有用,因为它们基本上每次都被每个声明的标签实例化/执行一次。但是,在正常视图中,您依赖于更多因素:例如,当 EL 依赖于某些 JSF UIData/repeated 变量时,JSTL 不会像预期的那样运行,因为此信息在视图构建期间不可用。
【解决方案2】:

我可以通过将facet 换成attribute 来解决这个问题。总结一下:

这行得通

<p:panel ...>
    <f:attribute name="footer" value="#{message}"/>
    <!-- ... -->
</p:panel>

但这不起作用

<p:panel footer="#{message}">
    <!-- ... -->
</p:panel>

这个也不行

<p:panel ...>
    <f:facet name="footer">#{message}</f:facet>
    <!-- ... -->
</p:panel>

也不是这个

<p:panel ...>
    <f:facet name="footer">
        <h:outputText value="#{message}" rendered="#{!empty message}"/>
    </f:facet>
    <!-- ... -->
</p:panel>

“作品”是指:

“当#{message} 为空或null 时,呈现no 页脚——不仅仅是一个空页脚;否则,使用指定的文本正确呈现页脚。”


PrimeFaces forum thread on this issue

【讨论】:

  • 哦,有趣的一个。你是怎么发现的?幸运事故?挖了渲染器源?
  • @BalusC: 反复试验 - 所以,当然,幸运的意外 :) 学习 JSF et al
  • 无知有时是一种幸福。事实证明,构面实际上是作为属性存储的(优点是您可以在其中声明 UI 组件)。很高兴知道。
  • @BalusC:您是说构面只是可以包含其他 JSF 标记的属性?这是有道理的。这是 PrimeFaces 的事情,还是 JSF 范围内的事实?
  • Facets 从一开始就在 JSF 中。例如。 &lt;h:dataTable&gt;&lt;f:facet name="footer"&gt;&lt;tfoot&gt;。但它们不作为属性存储在标准 JSF impl 中。我不确定 PrimeFaces 是如何做到的,因为我需要挖掘它的来源。
【解决方案3】:

我在普通的 JSF 中遇到过类似的问题。我不确定&lt;p:panel&gt; 是如何呈现的,但如果它呈现为表格,你可以试试这个:

首先,像这样声明一个 CSS 类:

.HideFooter tfoot {
    display: none;
}

然后在面板上有条件地设置该类:

<p:panel styleClass="#{renderFooterCondition ? null : 'HideFooter'}">

页脚仍以 JSF 方式呈现,但在用户代理查看时不显示且不占用页面中的任何空间。

【讨论】:

    【解决方案4】:

    您可以声明一个 ui:param 并让模板在渲染时检查参数。

    然后可以将模板中的构面声明为:

    <f:facet name="#{hideFooter == null or not hideFooter ? 'footer' : ''}">
         #{message}
    </f:facet>
    

    然后任何页面都可以声明这个参数

    <ui:param name='hideFooter' value='#{some rule}' />
    

    并为参数设置适当的规则。对于任何没有声明参数的页面,都会显示页脚。

    【讨论】:

      【解决方案5】:

      为什么不将页脚的内容封装到具有 render 属性的 panelGroup 中?

      这边:

      <p:panel header="some text">
          <f:facet name="footer">
          <h:panelGroup rendered="#{!empty message}">
              #{message}
          </h:panelGroup>
          </f:facet>
          <!-- ... -->
      </p:panel>
      

      我在我的 weapp 中执行此操作,它可以正常工作,没有渲染页脚。

      虽然我不使用 primefaces,但我使用 h:datatable 使用它,但我认为它也必须使用 p:panel。

      【讨论】:

        【解决方案6】:

        我使用 ui:fragment 成功解决了这个问题

        <ui:fragment rendered="...Test...">
        <f:facet name="footer">
        ...
        </f:facet>
        </ui:fragment>
        

        例如可以有条件地渲染 primefaces 数据表的页脚(该 facet 的渲染属性不起作用)。

        【讨论】:

        • 在 p:dataTable (Primefaces 5.3) 的选定 p:column 中的 &lt;f:facet name="footer"&gt; 中为我工作。
        • 编辑:撤销我的 +1。在选定的 p:dataTable 的 p:column 中 &lt;f:facet name="footer"&gt; 对我不起作用(Primefaces 5.3)。起初我以为是这样,但这只是针对“不渲染”的情况;我在进一步测试后发现它在所有情况下都会停止页脚刻面渲染。
        • 嗯,是的,我只打算条件渲染。你还有什么期待?
        【解决方案7】:

        不确定这对您的页脚效果如何,但我在尝试有条件地渲染图例时遇到了同样的问题。我通过在 facet 标记内的任何内容上使用渲染来修复它。

        <p:fieldset>
        <f:facet name="legend">
            <h:outputText value="#{header1}" rendered="#{header1.exists}"/>
            <h:outputText value="#{header2}" rendered="#{not header1.exists}"/>
        </f:facet>
        content
        </p:fieldset>
        

        我在使用 ui:repeat 尝试 c:if 时遇到了困难,所以这是我的解决方案。与您的问题不太一样,但类似。

        【讨论】:

        • 这个特殊的例子可以由&lt;p:fieldset legend="#{header1.exists ? header1 : header2}"&gt;完成。
        【解决方案8】:

        Facets 不打算呈现 HTML,这就是它没有 render 属性的原因。构面将功能添加到页面。术语方面可能是一个糟糕的名称选择。这很模棱两可。

        ..如果 ITworld 的 Phil Johnson 编制的列表是正确的,那么 开发人员最难做的事情就是name things

        即。

        JSF facets

        项目构面是一个特定的功能单元,您可以在需要该功能时将其添加到项目中。将项目方面添加到项目时,它可以根据特定项目的特征向项目添加性质、构建器、类路径条目和资源。 JSF facets 定义了启用 JSF 的 Web 应用程序的特征。 JSF facets 指定适用于您的 JSF 项目的要求和约束。

        JSF facets 为您的 Web 应用程序提供一组行为和功能。

        【讨论】:

          【解决方案9】:

          我尝试了这个解决方案,没问题。 (http://www.coderanch.com/t/431222/JSF/java/dynamically-set-panel-header-condition)

          <rich:dataGrid value="#{myMB.student.list}" rendered="#{!empty myMB.student and !empty myMB.student.list}" var="st" rowKeyVar="row">
              <rich:panel>                                            
                  <f:facet name="header">
                  <h:panelGroup id="panelHeader">
                      <h:outputText value="Just one student" id="header1" required="true" rendered="#{!myMB.manyStudents}"/>
                      <h:outputText value="#{row+1}º Student"  id="header2" required="true"  rendered="#{myMB.manyStudents}"/>
                      </h:panelGroup>                                 
                  </f:facet>
          <rich:panel>
          

          【讨论】:

            【解决方案10】:

            这是对 Ludovic Pénet 答案的反驳。

            这在 &lt;f:facet name="footer"&gt; 中对我有用,在 p:dataTable (Primefaces 5.3) 的选定 p:column 项目中:

            ...

            注意ui:fragmentf:facet 内部,而不是在外部(不包装)它。当每个页脚方面都经过测试以不呈现时,它肯定会完全删除整行(据我所知,与ui:fragment 中的内容无关)。

            【讨论】:

              【解决方案11】:

              试试这个,来自 primefaces 网页

              <p:columnGroup type="footer">
                  <p:row>
                      <p:column colspan="3" style="text-align:right" footerText="Totals:" />
                      <p:column footerText="your value in ajax" />
              
                      <p:column footerText="your value in ajax" />
                  </p:row>
              </p:columnGroup>
              

              点击here,查看primefaces的网页

              【讨论】:

                【解决方案12】:

                对于那些试图隐藏 footer 而不是 header,但语法 component.facets.footer 不起作用的人,应该试试这个:

                <p:panel id="panelContent">
                    <c:if test="#{not empty cc.facets.footer}">
                        <f:facet name="footer" height="100%">
                           your content
                        </f:facet>
                    </c:if>
                </panel>
                

                【讨论】:

                  猜你喜欢
                  • 2021-11-19
                  • 2018-06-30
                  • 2014-11-26
                  • 2012-11-20
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-03-24
                  • 2013-05-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多