1

这个例子来自一本关于 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>仍应允许使用 of:

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

有没有更多的“Facelets 方式”来做到这一点(并且仍然需要使用<c:forEach>)?

更新: 而不是<c:if>仍然可以使用 eg<h:outputPanel>和它的rendered-attribute,但仍然没有 Java-less 替代fn:toUpperCase().

我要求仅用于学习目的。我认为<ui:repeat>带有转换器的解决方案是最干净的,并且最能代表 JSF 应该如何使用。你也这么认为吗?

4

1 回答 1

3

至于<c:if>,JSTL 的 JSF 替代方案是任何组件上<c:if>rendered属性。例如,<h:panelGroup><h:outputText>。如果没有指定应以 HTML 结尾的属性(如idor ),则这些组件不会生成额外的标记styleClass,否则它们会生成<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。由于这完全发生在客户端,您唯一的问题可能是浏览器支持

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

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

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

我认为带有转换器的解决方案是最干净的,并且最能代表 JSF 应该如何使用。你也这么认为吗?

我是“为工作使用正确的工具”的忠实粉丝。使用 JSTL 标记有条件地构建 JSF 组件树。使用 JSF 组件生成 HTML。而已。另请参阅JSF2 Facelets 中的 JSTL... 有意义吗?

于 2013-08-01T12:53:40.317 回答