我想根据bean值设置一个ui:param,我想用c:if是个好主意。所以我在页面中输入了以下代码:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:wai="http://www.id.ethz.ch/wai/jsf"
template="/view/listView.xhtml">
<c:if test="#{subscriptionListController.model.listViewName eq 'mySubscriptions'}">
<ui:param name="title" value="#{msg.subscriptionTitleMySubscriptions}"/>
</c:if>
<c:if test="#{subscriptionListController.model.listViewName eq 'paidSubscriptions'}">
<ui:param name="title" value="#{msg.subscriptionTitlePaidSubscriptions}"/>
</c:if>
<c:if test="#{subscriptionListController.model.listViewName eq 'allSubscriptions'}">
<ui:param name="title" value="#{msg.subscriptionTitleAllSubscriptions}"/>
</c:if>
....
但参数未设置...
如果我打印出#{subscriptionListController.model.listViewName eq 'mySubscriptions'}
的值,我会在相应的情况下得到真,而在其他两种情况下则为假。
一开始我只有两种可能性并用三元运算符解决它:
<ui:param name="title" value="#{subscriptionListController.model.listViewName eq 'mySubscriptions' ? msg.subscriptionTitleMySubscriptions : msg.subscriptionTitlePaidSubscriptions}"/>
它有效。但现在我有更多的可能性......
我做错了什么?
答案 0 :(得分:11)
如<ui:composition template>
所示,此页面代表模板客户端。
<ui:param>
以外的任何<ui:define>
适用于主模板(您在template
属性中声明的文件),并在模板客户端本身内被忽略。如果您打算为模板客户端内部准备变量,则应将<ui:param>
放在<ui:define>
内。
但还有另一件事:<ui:param>
的最初目的是将变量传递给<ui:composition template>
,<ui:decorate template>
或<ui:include src>
引用的文件,而不是准备/设置变量在当前facelet上下文中。对于在当前EL上下文中准备/设置变量的唯一功能要求,您最好使用JSTL <c:set>
来完成工作。您可以使用<ui:param>
,但这不是它的原始意图,并且在较旧的MyFaces版本中无法正常工作。
因此,所以:
<ui:define>
<c:if test="#{subscriptionListController.model.listViewName eq 'mySubscriptions'}">
<c:set var="title" value="#{msg.subscriptionTitleMySubscriptions}"/>
</c:if>
<c:if test="#{subscriptionListController.model.listViewName eq 'paidSubscriptions'}">
<c:set var="title" value="#{msg.subscriptionTitlePaidSubscriptions}"/>
</c:if>
<c:if test="#{subscriptionListController.model.listViewName eq 'allSubscriptions'}">
<c:set var="title" value="#{msg.subscriptionTitleAllSubscriptions}"/>
</c:if>
...
</ui:define>
无关,您可以按如下方式对其进行优化,而不需要一个只能在每个订阅类型中增长的不可维护的<c:if>
组:
<ui:define>
<c:set var="subscriptionTitleKey" value="subscriptionTitle.#{subscriptionListController.model.listViewName}">
<c:set var="title" value="#{msg[subscriptionTitleKey]}"/>
...
</ui:define>
使用这些键
subscriptionTitle.mySubscriptions = Title for my subscriptions
subscriptionTitle.paidSubscriptions = Title for paid subscriptions
subscriptionTitle.allSubscriptions = Title for all subscriptions
答案 1 :(得分:2)
您正在使用JSTL与Facelets。 JSTL在视图构建期间执行,而不是在呈现阶段执行。此外,在JSF2库中处理它们存在一些问题 - 例如在较旧的Mojarra版本中,它们不适用于具有部分状态保存的视图范围bean - 请参阅https://stackoverflow.com/a/3343681)。这就是你的EL表达有效的原因。
解决方案是避免JSTL - 使用ui:repeat而不是c:forEach和EL表达式和条件渲染而不是c:if。