【问题标题】:Why is <ui:fragment rendered> not evaluated on <h:outputStylesheet> and <h:outputScript>为什么没有在 <h:outputStylesheet> 和 <h:outputScript> 上评估 <ui:fragment render>
【发布时间】:2015-11-20 12:19:35
【问题描述】:

我有一个如下的 JSF 2 主模板:

<!DOCTYPE html>
<html lang="#{localeManager.language}" 
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html">

    <f:view locale="#{localeManager.locale}">
        <h:head>
            <meta charset="UTF-8" />
            <meta http-equiv="X-UA-Compatible" content="IE=edge" />
            <meta name="viewport" content="width=device-width, initial-scale=1" />
            <title><ui:insert name="title">Default Title.</ui:insert></title>

            <!-- Development Stylesheets -->
            <ui:fragment rendered="#{facesContext.application.projectStage eq 'Development'}">
                <h:outputStylesheet name="css/bootstrap.css" library="bootstrap" />
                <h:outputStylesheet name="css/font-awesome.css" library="fontawesome" />
            </ui:fragment>

            <h:outputStylesheet name="css/main.css" library="core" />
            <ui:insert name="header-stylesheet" />

            <!-- Production Stylesheets -->
            <ui:fragment rendered="#{facesContext.application.projectStage eq 'Production'}">
                <h:outputStylesheet name="css/bootstrap.min.css" library="bootstrap" />
                <h:outputStylesheet name="css/font-awesome.min.css" library="fontawesome" />
            </ui:fragment>

            <ui:insert name="header-script" />
        </h:head>

        <h:body>
            <div id="wrapper">
                <div id="header">
                    <ui:insert name="header">Default content</ui:insert>
                </div>

                <div id="body">
                    <ui:insert name="body">Default body</ui:insert>
                </div>

                <div id="footer">
                    <ui:insert name="footer">Default footer</ui:insert>
                </div>
            </div>

            <!-- Development Scripts -->
            <ui:fragment rendered="#{facesContext.application.projectStage eq 'Development'}">
                <h:outputScript name="jquery-2.1.4.js" library="jquery" />
                <h:outputScript name="js/bootstrap.js" library="bootstrap" />
            </ui:fragment>

            <!-- Production Scripts -->
            <ui:fragment rendered="#{facesContext.application.projectStage eq 'Production'}">
                <h:outputScript name="jquery-2.1.4.min.js" library="jquery" />
                <h:outputScript name="js/bootstrap.min.js" library="bootstrap" />
            </ui:fragment>
            <ui:insert name="body-script" />
        </h:body>
    </f:view>
</html>

在 Wildfly 9.0.1 Final 中部署它时,我看到我的所有 &lt;ui:fragment&gt; 属性都被渲染了。这是为什么?我正在使用 JSF 2.2 框架进行开发。

我的面孔项目阶段是Development。

注意:在 SO 中关于这个问题的所有答案中,没有一个是解决这个问题的方法(所以我做了功课)。

【问题讨论】:

    标签: jsf jsf-2 facelets conditional-rendering


    【解决方案1】:

    &lt;h:outputStylesheet&gt; 和 &lt;h:outputScript&gt; 是特殊组件。他们将在视图构建期间通过UIViewRoot#addComponentResource() (see Mojarra source code here) 将声明的样式表或脚本资源添加到视图中。

    这与组件或其父组件的rendered 条件无关。实际上,它们基本上被重新定位到&lt;h:head&gt; 或&lt;h:body&gt; 的最后,这取决于target 属性的值,导致它们不再位于&lt;ui:fragment&gt; 内。

    然后,在渲染过程中,只考虑它们自己的rendered 属性(实际上也考虑了&lt;h:head&gt;,但那没有意义)。

    你有两个选择:

    1. 使用视图构建时间标签有条件地将它们添加到视图中。无论如何,项目阶段条件都是应用范围。

      <!-- Development Stylesheets -->
      <c:if test="#{facesContext.application.projectStage eq 'Development'}">
          <h:outputStylesheet ... />
          <h:outputStylesheet ... />
      </c:if>
      
      <!-- Production Stylesheets -->
      <c:if test="#{facesContext.application.projectStage eq 'Production'}">
          <h:outputStylesheet ... />
          <h:outputStylesheet ... />
      </c:if>
      
    2. 检查组件资源自己的rendered属性中的条件。如有必要,使用 &lt;c:set&gt; 创建一个短 EL 变量。

      <c:set var="dev" value="#{facesContext.application.projectStage eq 'Development'}" scope="application" />
      
      <!-- Development Stylesheets -->
      <h:outputStylesheet ... rendered="#{dev}" />
      <h:outputStylesheet ... rendered="#{dev}" />
      
      <!-- Production Stylesheets -->
      <h:outputStylesheet ... rendered="#{not dev}" />
      <h:outputStylesheet ... rendered="#{not dev}" />
      

    【讨论】:

    • 那么,如果我使用JSTL条件if,我不应该使用$而不是#吗?
    • 你可以,但这并不统一,而且对初学者来说是不必要的混乱。在 Facelets 中,${} 的行为与 #{} 完全相同,但在 JSP 中,${} 会立即(“静态”)评估,而 #{} 只会在每次调用时评估(“延迟”)。
    • 谢谢。我得到了可以使用 JSTL 条件 if 的东西。
    • 也谢谢,我花了好几个小时检查为什么我的 ui:fragment 周围的渲染属性不起作用。
    猜你喜欢
    • 2013-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-23
    • 2021-05-15
    • 1970-01-01
    • 1970-01-01
    • 2018-05-07
    相关资源
    最近更新 更多