问题
I have a composite component with a ui:repeat
and want to define the content of the ui:repeat
through the interface of the composite.
Following code is working in MyFaces but looks more like a hack since variable name varRepeat
must be known outside of composite and it only works if no other childrens are provided that should be rendered somewhere else.
View
Define content of the ui:repeat
<comp:myRepeater value="#{of:createIntegerArray(1,5)}">
<h:outputText id="varComp" value="#{varRepeat}"/>
</comp:myRepeater>
Composite myRepeater
<composite:attribute name="value" type="java.lang.Object"/>
<composite:implementation>
<ui:repeat var="varRepeat" value="#{cc.attrs.value}">
<composite:insertChildren/>
</ui:repeat>
</composite:implementation>
回答1:
That's the best you can get given that var
attribute doesn't support EL. To make it clear to the enduser, document the name of var
in <cc:interface shortDescription>
and/or <cc:attribute shortDescription>
.
<cc:interface>
<cc:attribute name="value" type="java.util.Collection"
shortDescription="A collection of items. Each item is exposed in EL under the variable name 'item'." />
<cc:interface>
<cc:implementation>
<ui:repeat value="#{cc.attrs.value}" var="item">
<cc:insertChildren />
</ui:repeat>
</cc:implementation>
Usage:
<my:repeat value="#{bean.list}">
<h:outputText value="#{item}" />
</my:repeat>
The OmniFaces showcase application has also a similar composite for long: <os:listDocs>:
<cc:implementation>
<c:set var="docs" value="#{page.current.documentation[cc.attrs.paths]}" />
<ui:fragment rendered="#{not empty docs}">
<h3>#{cc.attrs.header}</h3>
<ul>
<ui:repeat value="#{docs}" var="path">
<li><a href="#{cc.attrs.url}"><code>#{cc.attrs.label}</code></a></li>
</ui:repeat>
</ul>
</ui:fragment>
</cc:implementation>
Usage:
<os:listdocs header="VDL" paths="vdl" url="#{_vdlURL}#{path}.html" label="#{fn:replace(path,'/', ':')}" />
<os:listdocs header="API" paths="api" url="#{_apiURL}#{path}.html" label="#{fn:replace(path,'/', '.')}" />
<os:listdocs header="Source code" paths="api" url="#{_srcURL}#{path}.java" label="#{fn:replace(path,'/', '.')}" />
As a design hint, if you use a sensible attribute name for the collection, the var
may become more self-documenting. E.g. ask for items
as value and provide a var="item"
.
<my:repeat items="#{[1,2,3,4,5]}">
<h:outputText value="#{item}"/>
</my:repeat>
来源:https://stackoverflow.com/questions/32302211/how-to-define-the-content-of-repeater-inside-composite-through-its-interface