How to define the content of repeater inside composite through its interface?

吃可爱长大的小学妹 提交于 2019-12-07 15:37:55

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!