这个例子来自一本关于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>
。 rendered
和fn:toUpperCase()
- 属性,但仍然没有<ui:repeat>
的无Java替换。
我只是要求学习目的。我认为使用转换器的{{1}} - 解决方案是最干净的,并且代表了JSF应该如何使用的最大化。你也这么认为吗?
答案 0 :(得分:3)
对于<c:if>
,JSTL <c:if>
的JSF替代是任何组件的rendered
属性。例如,<h:panelGroup>
或<h:outputText>
。如果没有指定属于HTML的结果,如id
或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
。由于这完全发生在客户端,因此您唯一的问题可能是browser support。
<h:outputText value="#{item}" style="text-transform: uppercase" />
(注意:这只是一个示例,通常的做法是将样式放在由.css
加载的<h:outputStylesheet>
文件中1>}
<h:outputText value="#{item}" styleClass="uppercased" />
我认为使用转换器的-solution是最干净的,并且代表了JSF应该如何使用。你也这么认为吗?
我是#34的忠实粉丝;使用合适的工具来完成工作&#34;。使用JSTL标记有条件地构建JSF组件树。使用JSF组件生成HTML。就是这样。另请参阅JSTL in JSF2 Facelets... makes sense?