Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
259 views
in Technique[技术] by (71.8m points)

java - Mixing JSF tags with JSTL tags gives strange results

I have this piece of code:

 <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>

As you see, i render that outputPanel only when columnRendered is true.

Well, there are situations when this (used only for tests to approve what it should do):

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

is true so it should enter in c:if and switch columnRendered to false. But it doesn't, so columnRendered is true forever...

Do you know why?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

JSF and JSTL doesn't run in sync as you'd expect from the coding. JSTL runs during build time of the view (when the JSF component tree is to be populated) and JSF runs during render time of the view component tree (when HTML output is to be generated). You can visualize it as follows: JSTL runs first from top to bottom and then hands over the result to JSF which in turn runs from top to bottom again.

In your particular case, the object instance is never present in JSTL.

Instead of c:forEach, you should use ui:repeat and instead of c:if you should use JSF component's rendered attribute. I'd like to give a rewrite of the code, but the usage of hideTypes is a mess. Rather convert it to a List<String> in the model and it'll be much easier to do with pure JSF. Here's a kickoff example assuming that hideTypes is a 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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...