用JSF-tags替换<c:if>和fn:toUpperCase()</c:if>

时间:2013-08-01 11:49:39

标签: jsf-2 jstl facelets

这个例子来自一本关于JSF的书。练习是重构以下Facelets代码,同时消除<c:if>fn:toUpperCase()。允许使用<c:forEach>

#{myBean.numbers}返回String["one","two","three"]

由于这本书是关于JSF而不是关于Java的,我认为现有的Java代码是不可触及的。但我想不出另一种方法只在Facelets中这样做。

<c:forEach var="item" items="#{myBean.numbers}">
    <c:if test="#{not fn:endsWith(item,'o')}">
        #{item}
    </c:if>
    <c:if test="#{fn:endsWith(item,'o')}">
        #{fn:toUpperCase(item)}
    </c:if>
</c:forEach>

我唯一能想到的是使用有条件地使用String#toUpperCase()的转换器然后我仍然不明白为什么仍然允许使用<c:forEach>

<ui:repeat var="item" value="#{myBean.numbers}">
     <h:outputText value="#{item}" converter="conditionalConverter"/>
</ui:repeat>

是否有更多“Facelets方式”来执行此操作(仍然需要使用<c:forEach>)?

更新 可以使用例如<c:if>而不是<h:outputPanel>renderedfn:toUpperCase() - 属性,但仍然没有<ui:repeat>的无Java替换。

我只是要求学习目的。我认为使用转换器的{{1}} - 解决方案是最干净的,并且代表了JSF应该如何使用的最大化。你也这么认为吗?

1 个答案:

答案 0 :(得分:3)

对于<c:if>,JSTL <c:if>的JSF替代是任何组件的rendered属性。例如,<h:panelGroup><h:outputText>。如果没有指定属于HTML的结果,如idstyleClass,则这些组件不会生成额外的标记,否则会生成<span>

这是两个例子:

<h:panelGroup rendered="#{not fn:endsWith(item,'o')}">
    #{item}
</h:panelGroup>
<h:outputText value="#{fn:toUpperCase(item)}" rendered="#{fn:endsWith(item,'o')}" />

至于fn:toUpperCase(),JSF别无选择。我不确定为什么你需要一个JSF替代品,因为它本质上不是一个标签,而是一个简单的EL函数,它在JSTL和JSF标签中都是完全可用的。在任何情况下,您都可以在必要时使用CSS text-transform: uppercase。由于这完全发生在客户端,因此您唯一的问题可能是browser support

<h:outputText value="#{item}" style="text-transform: uppercase" />

(注意:这只是一个示例,通常的做法是将样式放在由.css加载的<h:outputStylesheet>文件中}

<h:outputText value="#{item}" styleClass="uppercased" />

  

我认为使用转换器的-solution是最干净的,并且代表了JSF应该如何使用。你也这么认为吗?

我是#34的忠实粉丝;使用合适的工具来完成工作&#34;。使用JSTL标记有条件地构建JSF组件树。使用JSF组件生成HTML。就是这样。另请参阅JSTL in JSF2 Facelets... makes sense?