mutually exclusive? I just don't understand: If I want my comp...">

Are JSF2 composite components: # {cc.childCount} and <composite: insertChildren / "> mutually exclusive?

I just don't understand: If I want my composite component to insert children, I used <composite:insertChildren/> , but #{cc.childCount} always returns 0 in this case. On the other hand, if I do not use <composite:insertChildren/> , I always get the correct childCount without playing the children. Why is this happening?

All I want to do in my component is to display some default panel if there are no children and not display it in another case - a behavior similar to <ui:insert name="param_name">default value</ui:insert> . So I need both insertChildren and childCount, which don't seem to work together.

Here is the code:

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

If I use the implementation below, I get 2 as expected

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

When insertChildren used, I get both images and 0 at the end:

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

While my goal is:

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

Any ideas / workarounds?

+6
source share
3 answers

Place the children in the Panel group with an identifier (for example, children).

Then

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

will give you the correct value. Good luck

+5
source

In the cc: insertChildren documentation:

Any child components or template text in the composite component tag on the usage page will be re-marked in the composite component at the point indicated by this tagging in this section.

Thus, using <cc:insertChildren> , you actually move the children from component #{cc} to the component in which you specified <cc:insertChildren> , effectively making them (great) * grandchildren #{cc} . To get easy access to these displaced children, I use <ui:fragment> as a parent:

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

Now you can use #{childContainer.childCount} to count the numbers you specify for the composite component. This solution is a bit fragile: you can use your composite component only once for viewing due to snapping. Of course, this problem can be solved by associating the FacesComponent bean with your composite component. Bean first:

 package com.stackoverflow.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; } } 

And now you can bind this class to a composite component:

 <?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> 

You now have a composite component with <cc:insertChildren> and direct access to these children.

EDIT: added BalusC comment.

+3
source

I had a similar problem. I switched to c:if and it worked, so in your case it will be

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

Source: https://habr.com/ru/post/890706/


All Articles