我有这段代码:
<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永远是正确的…
你知道为什么吗?
JSF和JSTL不会像您期望的那样同步运行。JSTL在视图的构建期间(要填充JSF组件树)运行,而JSF在视图的组件树的呈现期间(要生成HTML输出)运行。您可以将其可视化如下:JSTL首先从上到下运行,然后将结果交给JSF,后者又从上到下运行。
在您的特定情况下,该对象instance永远不会出现在JSTL中。
instance
代替c:forEach,应该使用ui:repeat,而不是c:if使用JSF组件的rendered属性。我想重写代码,但是的用法hideTypes很乱。而是将其转换List<String>为模型中的,使用纯JSF会更加容易。这是一个假设hideTypes为的启动示例List<String>:
c:forEach
ui:repeat
c:if
rendered
hideTypes
List<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>