9

我有三个值,我希望在前两个值的情况下呈现一个组件,在第三个值的情况下呈现另一个组件

下面,我有我的页面:

页面.xhtml

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

这就是我的页面的定义方式。我还添加了以下命名空间:xmlns:c="http://java.sun.com/jsp/jstl/core.

我测试了在测试中定义的值是否<c:when>返回“true”或“false”,并且确实如此。

我的问题是<c:when>从未评估过。<c:otherwise>始终呈现该值。我错过了什么吗?是不是因为条件渲染在里面<ui:repeat>,所以没有评估 when ?

任何帮助将不胜感激。提前致谢

4

2 回答 2

12

您需要删除 c:choose,因为正如 @Jens 在评论中所述,它们在不同的阶段进行处理。您可以将 JSTL 与 JSF 结合使用,但必须遵守它们的解析顺序。阅读 BalusC 的精彩答案,他摇摆不定。

至于您的需要,您可以使用render 属性,有条件地输出您的文本:

<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>
于 2013-05-27T12:48:55.817 回答
10

只是为了补充 Mindwin 的答案,您需要了解它<c:choose>是一个标签处理程序,什么时候<ui:repeat>是一个 UI 组件。前者是在构建组件树时评估的,而后者是在渲染视图时评估的,即在稍后的时间。从这个角度来看,依赖于你的代码是有问题的,因为它在发挥作用时没有被var评估。<ui:repeat><c:choose>

这里有两件事要记住。

将迭代标记处理程序<c:forEach>, 与您的内容一起使用:

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

使用这种方法,两个标签同时运行(正在构建视图),因此不会发生冲突。请记住,如果您的 bean 是视图范围的,它将在每次请求时重新创建。

使用带有rendered属性的 UI 组件:

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

在这种情况下,一切都同时运行(正在渲染视图)。请注意,您可以使用属性呈现一大堆 HTML,例如,<ui:fragment>以及某些特定的 JSF 标记(如)。<h:outputText>rendered


最后,继续阅读经典帖子:JSF2 Facelets 中的 JSTL……有意义吗?,以全面了解标签处理程序和 UI 组件之间的关系。

于 2013-05-27T13:41:47.120 回答