jsf 2 - mkyong - Configurando ui: param condicionalmente
ui:composition primefaces (2)
Quiero establecer un ui: param dependiendo de un valor de bean y pensé usar c: si era una buena idea. Entonces puse en mi página el siguiente código:
<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>
....
pero el parámetro no está establecido ...
Si dejo imprimir el valor de #{subscriptionListController.model.listViewName eq ''mySubscriptions''}
me hago verdadero en el caso correspondiente y falso en los otros dos casos.
Al principio tenía solo 2 posibilidades y las resolví con el operador ternario:
<ui:param name="title" value="#{subscriptionListController.model.listViewName eq ''mySubscriptions'' ? msg.subscriptionTitleMySubscriptions : msg.subscriptionTitlePaidSubscriptions}"/>
Y funcionó. Pero ahora tengo más posibilidades ...
¿Qué estoy haciendo mal?
Según lo indicado por <ui:composition template>
, esta página representa un cliente de plantilla.
Cualquier <ui:param>
fuera <ui:define>
aplica a la plantilla maestra (el archivo que usted declaró en el atributo de template
) y se ignora dentro del cliente de la plantilla. Si tiene la intención de preparar variables para el cliente de plantilla, debe poner <ui:param>
dentro de <ui:define>
.
Pero hay otra cosa: el propósito original de <ui:param>
es pasar variables al archivo referenciado por <ui:composition template>
, <ui:decorate template>
o <ui:include src>
, no para preparar / establecer variables dentro del contexto de facelet actual. Para el único requisito funcional de preparar / establecer variables en el contexto EL actual, será mejor que use JSTL <c:set>
para el trabajo. Puede usar <ui:param>
para esto, pero este no es su intento original y no funcionó de esa manera en versiones anteriores de MyFaces.
Por lo tanto, así que:
<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>
Sin relación con el problema concreto, puede optimizar esto de la siguiente manera sin la necesidad de un grupo <c:if>
que no pueda ser mantenido <c:if>
que solo crezca con cada tipo de suscripción:
<ui:define>
<c:set var="subscriptionTitleKey" value="subscriptionTitle.#{subscriptionListController.model.listViewName}">
<c:set var="title" value="#{msg[subscriptionTitleKey]}"/>
...
</ui:define>
con esas llaves
subscriptionTitle.mySubscriptions = Title for my subscriptions
subscriptionTitle.paidSubscriptions = Title for paid subscriptions
subscriptionTitle.allSubscriptions = Title for all subscriptions
Estás usando JSTL con Facelets. JSTL se ejecuta durante el tiempo de compilación de la vista, y no en la fase de procesamiento. Además, hay algunos problemas con el procesamiento de las mismas en las bibliotecas JSF2, como en las versiones anteriores de Mojarra, donde no funcionaban en los beans view view con ahorro de estado parcial, consulte https://.com/a/3343681 . Esta es la razón por la cual tu expresión EL ha funcionado.
La solución es evitar JSTL: use ui: repita en su lugar c: para cada expresión EL y representación condicional en lugar de c: if.