在复合组件内迭代时公开列表的项目

时间:2012-06-17 12:51:45

标签: java jsf facelets composite-component uirepeat

我正在迭代复合组件中的项列表。我希望公开列表中的每个项目,以便可以在此复合组件的子组件中使用它们,以创建如何显示列表中所有项目的模板。

这是我的复合组件实现:

customList.xhtml

<ui:component
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:cc="http://java.sun.com/jsf/composite"
    xmlns:ui="http://java.sun.com/jsf/facelets">    

    <cc:interface>
    </cc:interface>

    <cc:implementation>       
        ...
        ...   
        <ui:repeat value="#{listRetriever.list}" var="item">
            <cc:insertChildren />
        </ui:repeat>

    </cc:implementation>
</ui:component>

现在我想在我的页面中定义复合组件的子组件时使用#{item}(类似于h:dataTableui:repeat)。

  <my:customList>
        #{item}                <!--- over here--->
  </my:customList>

2 个答案:

答案 0 :(得分:2)

这不适用于<cc:insertChildren> <ui:repeat>,因为<cc:insertChildren>在视图构建期间进行评估,而不是在视图渲染时间内进行评估。 #{item}仅在视图渲染时可用,因为<ui:repeat>仅在视图渲染时间内运行。

当您使用JSTL <c:forEach>时它会起作用,因为它也会在视图构建期间进行评估,例如<cc:insertChildren>本身。

xmlns:c="http://java.sun.com/jsp/jstl/core"
...
<c:forEach items="#{listRetriever.list}" var="item">
    <cc:insertChildren />
</c:forEach>

当你在另一个重复的JSF组件中依次使用复合时要小心,那么它将不起作用。另请参阅JSTL in JSF2 Facelets... makes sense?

除了创建扩展UIDataUIRepeat的自定义组件之外,另一种方法是使用<ui:decorate>代替。

首先使customList.xhtml成为普通模板:

<ui:composition
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
>
    ... 
    ...  
    <ui:repeat value="#{list}" var="item">
        <ui:insert name="item" />
    </ui:repeat>
    ...
    ...
</ui:composition>

然后您可以按如下方式使用它:

<ui:decorate template="customList.xhtml">
    <ui:param name="list" value="#{bean.list}" />
    <ui:define name="item">
        #{item}
    </ui:define>
</ui:decorate>

答案 1 :(得分:1)

这些天我试图做类似的事情,没有解决。

我的解决方案,我自己的组件上var属性的值永远不能配置。所以保持固定在名称“var”,并始终暴露给我的组件,我使用变量“var”。

mi代码示例:

<强>组件: 文件:listadoPaginado.xhtml

<composite:interface>
    <composite:attribute name="id" required="true" 
                         displayName="ID if component" 
                         shortDescription="ID of component" />
    <composite:attribute name="value" required="true" 
                         displayName="List with values to iterate"/>  
</composite:interface>

<!-- Implementacion de la estructura del componente -->
<composite:implementation>
    <h:panelGroup id="#{cc.attrs.id}_panel_comp">
        <br/>
        <div  style="#{cc.attrs.style}">

            <ui:repeat  var="var" value="#{cc.attrs.value.model}">
                <composite:insertChildren/>
            </ui:repeat>
        </div>
    </h:panelGroup>
</composite:implementation>

使用组件

<gb:listadoPaginado id="listado_garantias"
                            value="#{beanTest.myList}">
 <p:panel>
     <p:panelGrid>
         <p:row>
              <p:column>
                   <h:outputLabel value="#{var.description}"/>
               </p:column>
               <p:column>
                    <p:inputText value="#{var.longDescription}"/>
                </p:column>
          </p:row>
       </p:panelGrid>
   </p:panel>