c:choose not working in JSF

前端 未结 2 1844
花落未央
花落未央 2020-12-20 15:25

I have three values and I want one component to be rendered in the case of first two values and another component for the third value

Below, I have my page :

相关标签:
2条回答
  • 2020-12-20 15:44

    You need to remove the c:choose, because as @Jens stated on the comments, they are processed in different phases. You can use JSTL in tandem with JSF, but have to respect the order they are resolved. read the fine answers by BalusC, he rocks.

    As for your needs, you can use the rendered attribute, to conditionally output your text:

    <ui:repeat value="#{bean.value}" var="data">
        <h:outputText rendered="#{data.thirdValue == 'content'}" value="Wrong value"/>
        <h:outputText rendered="#{data.thirdValue != 'content'}" value="Correct!"/>
    </ui:repeat>
    
    0 讨论(0)
  • 2020-12-20 15:47

    Just to add to Mindwin's answer, you need to understand that <c:choose> is a tag handler, when <ui:repeat> is a UI component. The former is evaluated while component tree is being built, and the latter - while the view is being rendered, i.e. at a later time. In this light, depenence upon var of <ui:repeat> is what is wrong with your code, as it hasn't been evaluated when <c:choose> comes into play.

    There are two things to be remembered here.

    Use an iterative tag handler, <c:forEach>, with your contents:

    <c:forEach items=#{bean.values} var="data">
        <c:choose>
            <c:when  test="#{data.thirdValue == 'content'}">
                <h:outputText value="Wrong value"/>
            </c:when>
            <c:otherwise>
                Correct!
            </c:otherwise>
        </c:choose>
    </c:forEach>
    

    With this approach both tags run at the same time (view is being built), so the conflicts won't occur. Just remember that in case your bean is view scoped it will be recreated upon every request.

    Use UI component with rendered attribute:

    <ui:repeat value=#{bean.values} var="data">
        <h:outputText rendered="#{data.thirdValue == 'content'}" value="Wrong value"/>
        <ui:fragment rendered="#{data.thirdValue != 'content'}">
            <h1>Correct</h1>
        </ui:fragment>
    </ui:repeat>
    

    In this case everything runs as well at the same time (view is being rendered). Note that you can render a whole bunch of HTML with, for example, <ui:fragment>, as well as some certain JSF tags like <h:outputText>, by using a rendered attribute.


    Ultimately, go ahead with the classic post: JSTL in JSF2 Facelets… makes sense?, to get a full understanding of relationship between tag handlers and UI components.

    0 讨论(0)
提交回复
热议问题