将JSF标记与JSTL标记混合会产生奇怪的结果

时间:2010-11-11 13:24:25

标签: java jsf jstl

我有这段代码:

 <c:if test="#{utils.getCounterOfCharOccurence(hideTypes, ';') != 0}">
   <ui:repeat value="#{document.instanceList}" var="instance">
    <c:set var="columnRendered" value="true"></c:set>
    <c:forEach items="${hideTypes.split(';')}"
               var="hideType">
     <h:outputText value="#{hideType eq instance.documentInstanceType.mimeType}"/>
     <c:if test="#{hideType eq instance.documentInstanceType.mimeType}">
      <c:set var="columnRendered" value="false"></c:set>
      <h:outputText value="#{columnRendered}|"/>
     </c:if>
    </c:forEach>
    <a:outputPanel rendered="#{columnRendered == 'true'}">
     <up:mimeTypeIcon type="#{instance.documentInstanceType.mimeType}"
                      icon="#{instance.documentInstanceType.iconPath}"
                      key="#{instance.instanceKey}" referenced="false"/>
    </a:outputPanel>
   </ui:repeat>

  </c:if>

如您所见,我只在columnRendered为true时呈现该outputPanel。

嗯,有些情况(仅用于测试以批准它应该做什么):

<h:outputText value="#{hideType eq instance.documentInstanceType.mimeType}"/>

为true,因此应输入c:if并将columnRendered切换为false。但它没有,所以columnRendered永远是真的......

你知道为什么吗?

1 个答案:

答案 0 :(得分:5)

JSF和JSTL没有按照您对编码的期望同步运行。 JSTL在视图的构建期间运行(当要填充JSF组件树时),并且JSF在视图组件树的渲染时间期间运行(当要生成HTML输出时)。您可以按如下方式对其进行可视化:JSTL首先从上到下运行,然后将结果移交给JSF,JSF又从上到下运行。

在您的特定情况下,JSTL中永远不会出现对象instance

您应该使用c:forEach而不是ui:repeat而不是c:if,而应使用JSF组件的rendered属性。我想重写代码,但hideTypes的使用是一团糟。而是将其转换为模型中的List<String>,并且使用纯JSF会更容易。假设hideTypesList<String>

,这是一个启动示例
<h:panelGroup rendered="#{not empty hideTypes}">
    <ui:repeat value="#{document.instanceList}" var="instance">
        <a:outputPanel rendered="#{!hideTypes.contains(instance.documentInstanceType.mimeType)}">
            <up:mimeTypeIcon type="#{instance.documentInstanceType.mimeType}"
                icon="#{instance.documentInstanceType.iconPath}"
                key="#{instance.instanceKey}" referenced="false"/>
        </a:outputPanel>
     </ui:repeat>
<h:panelGroup>