I've been doing some tests with composite components and I would like to understand why they produce different results when I use facets and children. Here are the files I'm using:
test.xhtml
-----------------------------------------------
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
xmlns="
http://www.w3.org/1999/xhtml"
xmlns:f="
http://java.sun.com/jsf/core"
xmlns:fn="
http://java.sun.com/jsp/jstl/functions"
xmlns:h="
http://java.sun.com/jsf/html"
xmlns:tags="
http://java.sun.com/jsf/composite/tags">
<h:head>
<title>Test</title>
</h:head>
<h:body>
<h1><h:outputText value="listFacets" /></h1>
<tags:listFacets value="#{fn:split('1,2,3', ',')}">
<f:facet name="content">
<h:outputText value="Test1" styleClass="test" />
<h:outputText value="Test2" styleClass="test" />
</f:facet>
</tags:listFacets>
<h1><h:outputText value="listChildren" /></h1>
<tags:listChildren value="#{fn:split('1,2,3', ',')}">
<h:outputText value="Test1" styleClass="test" />
<h:outputText value="Test2" styleClass="test" />
</tags:listChildren>
</h:body>
</html>
listFacets.xhtml
-----------------------------------------------
<html
xmlns="
http://www.w3.org/1999/xhtml"
xmlns:c="
http://java.sun.com/jsp/jstl/core"
xmlns:composite="
http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="value" />
<composite:facet name="content" />
</composite:interface>
<composite:implementation>
<c:forEach items="#{cc.attrs.value}" var="current">
<composite:renderFacet name="content" />
<hr />
</c:forEach>
<c:forEach items="#{cc.facets.content.children}" var="child">
#{child.attributes.styleClass}
<hr />
</c:forEach>
</composite:implementation>
</html>
listChildren.xhtml
-----------------------------------------------
<html
xmlns="
http://www.w3.org/1999/xhtml"
xmlns:c="
http://java.sun.com/jsp/jstl/core"
xmlns:composite="
http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="value" />
</composite:interface>
<composite:implementation>
<c:forEach items="#{cc.attrs.value}" var="current">
<composite:insertChildren />
<hr />
</c:forEach>
<c:forEach items="#{cc.children}" var="child">
#{child.attributes.styleClass}
<hr />
</c:forEach>
</composite:implementation>
</html>
The above produce the following HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="
http://www.w3.org/1999/xhtml">
<head><title>Test</title></head>
<body>
<h1>listFacets</h1>
<span class="test">Test1</span><span class="test">Test2</span>
<hr />
<span class="test">Test1</span><span class="test">Test2</span>
<hr />
<span class="test">Test1</span><span class="test">Test2</span>
<hr />
test
<hr />
test
<hr />
<h1>listChildren</h1>
<span class="test">Test1</span><span class="test">Test2</span>
<hr />
<hr />
<hr />
<hr />
<hr />
</body>
</html>
So, when using a single facet I'm able to print it multiple times inside a loop but the composite:insertChildren is printed only one. The children are printed multiple times when I replace c:forEach with ui:repeat but I really prefer using c:forEach. I had to check again but ui:repeat worked well in Jetty 6.1.18 but throw an exception in Tomcat 6.0.16.
Another cool feature of the facet is that I can access it's children and their attributes using the cc.facets.content.children collection. I wasn't able to achieve the same using the children variant. A bug I also noticed when doing the tests is that when there is a single child inside the facet the cc.facets.content.children doesn't work as expected. It works fine when there are multiple children inside the facet.
I'm wondering is this behavior expected by design. I don't need the single facet if I can use the composite:insertChildren functionality but so far the facet approach only satisfies my needs.
Thanks!
[Message sent by forum member 'rostislav' (rostislav)]
http://forums.java.net/jive/thread.jspa?messageID=358500