template diseño attribute jsf jsf-2 composite-component

diseño - templates jsf primefaces



Componentes compuestos JSF2: ¿son#{cc.childCount} y<composite: insertChildren/> mutuamente exclusivos? (3)

Simplemente no lo entiendo: si quiero que mi componente compuesto inserte elementos <composite:insertChildren/> , utilizo <composite:insertChildren/> pero #{cc.childCount} siempre devuelve 0 en ese caso. Por otro lado, si no uso <composite:insertChildren/> siempre obtengo el childCount correcto sin que se representen niños. ¿Por qué está sucediendo eso?

Todo lo que quiero hacer en mi componente es renderizar un panel "predeterminado" si no hay hijos y no lo renderizo en otro caso - comportamiento similar a <ui:insert name="param_name">default value</ui:insert> . Entonces necesito insertChildren y childCount que no parecen funcionar juntos.

Aquí está el código:

<my:test> <h:outputText value="child1" rendered="#{some.trueValue}"/> <h:outputText value="child2" rendered="#{some.trueValue}"/> <my:test>

Si utilizo la implementación a continuación, obtengo 2 procesados ​​como se esperaba

<composite:implementation> <h:outputText value="#{cc.childCount}"/> </composite:implementation>

Cuando insertChildren se usa, obtengo ambos hijos renderizados y 0 al final:

<composite:implementation> <composite:insertChildren/> <h:outputText value="#{cc.childCount}"/> </composite:implementation>

Mientras que mi objetivo es:

<composite:implementation> <composite:insertChildren/> <h:panelGroup rendered="#{cc.childCount == 0}"> some default data </h:panelGroup> </composite:implementation>

¿Alguna idea / solución?


Coloque a los niños en un PanelGroup con una identificación (por ejemplo, niños).

Entonces

#{component.findComponent(''children'').childCount}

le dará el valor correcto. ¡Buena suerte!


Tuve un problema similar. Cambié a c:if funcionó, por lo que en su caso sería

<composite:implementation> <composite:insertChildren/> <c:if test="#{cc.childCount == 0}"> some default data </c:if> </composite:implementation>


De la documentación de cc: insertChildren:

Cualquier componente secundario o texto de plantilla dentro de la etiqueta de componente compuesto en la página de uso se volverá a parentar en el componente compuesto en el punto indicado por la colocación de esta etiqueta dentro de la sección.

Entonces al usar <cc:insertChildren> mueves los elementos desde el componente #{cc} al componente en el que especificaste <cc:insertChildren> , convirtiéndolos en (grandiosos) * nietos de #{cc} . Para tener acceso fácil a estos niños reubicados, utilizo un <ui:fragment> como padre:

<ui:fragment binding="#{childContainer}"> <cc:insertChildren/> </ui:fragment>

Ahora puede usar #{childContainer.childCount} para contar los niños que ha especificado para su componente compuesto. Sin embargo, esta solución es un tanto frágil: solo puede usar su componente compuesto una vez por vista, debido a la unión. Por supuesto, este problema se puede resolver vinculando un bean FacesComponent a su componente compuesto. Primero el frijol:

package com..jsfinsertchildrenandcountexample; import javax.faces.component.FacesComponent; import javax.faces.component.UIComponent; import javax.faces.component.UINamingContainer; @FacesComponent(value = "myCompositeComponent") public class MyCompositeComponent extends UINamingContainer { private UIComponent childContainer; public UIComponent getChildContainer() { return childContainer; } public void setChildContainer(UIComponent childContainer) { this.childContainer = childContainer; } }

Y ahora puedes vincular esta clase a tu componente compuesto:

<?xml version=''1.0'' encoding=''UTF-8'' ?> <ui:component xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:cc="http://java.sun.com/jsf/composite" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" > <cc:interface componentType="myCompositeComponent"> </cc:interface> <cc:implementation> I have #{cc.childContainer.childCount} children. <ui:fragment binding="#{cc.childContainer}"> <cc:insertChildren/> </ui:fragment> </cc:implementation> </ui:component>

Ahora tiene un componente compuesto con <cc:insertChildren> y acceso directo a estos niños.

EDITAR: comentario incorporado BalusC.