仅在h:dataTable的第一行中渲染地图键

时间:2017-08-06 06:20:21

标签: jsf datatable

我一直在搜索如何使用c:forEach显示Map<String, ArrayList<String>>。我试图按字母顺序打印一个单词列表,并在与ArrayList中的第一个元素相同的行中显示一次键。

A Apple
  Arpa
  Adverb
B Background
  Ball
  Ballad
...

地图的签名是:

private Map<String, ArrayList<String>> procedures; 

我将其渲染如下:

<c:forEach items="#{obj.procedures}" var="entry" varStatus="counter"> 
    <h:column><h:outputText value="&#160;#{entry.key}"/> </h:column>
    <h:dataTable value="#{entry.value}" var="foo">                                       
        <h:column><h:outputText value="&#160;&#160;" /></h:column>                    
        <h:column><h:outputText value="&#160;#{foo}" /></h:column>                    
    </h:dataTable>
    <p:separator></p:separator>
</c:forEach>

但是,结果略有不同,因为第一个字母在第一个记录的上方显示一行,而不是显示在与值列表中的第一个记录相同的行中。

目前的结果:

A 
  Apple
  Arpa
  Adverb
_________________
B 
  Background
  Ball
  Ballad
    ...

干杯

1 个答案:

答案 0 :(得分:1)

您需要在<h:dataTable> ,而不是之外。只需移动<h:column>将地图密钥渲染回<h:dataTable>

<c:forEach items="#{obj.procedures}" var="entry">
    <h:dataTable value="#{entry.value}" var="foo">
        <h:column>#{entry.key}</h:column>
        <h:column>#{foo}</h:column>
    </h:dataTable>
</c:forEach>

这将产生:

A  Apple
A  Arpa
A  Adverb

B  Background
B  Ball
B  Ballad

然后,为了让它只显示在第一行,只需检查表的当前行索引是否等于0.您可以通过咨询UIData#getRowIndex()来获取它。您可以从<h:column>内部通过<h:dataTable>表达式访问父UIData #{component.namingContainer}

<c:forEach items="#{obj.procedures}" var="entry">
    <h:dataTable value="#{entry.value}" var="foo">
        <h:column><h:outputText value="#{entry.key}" rendered="#{component.namingContainer.rowIndex eq 0}" /></h:column>
        <h:column>#{foo}</h:column>
    </h:dataTable>
</c:forEach>
A  Apple
   Arpa
   Adverb

B  Background
   Ball
   Ballad

顺便说一下,使用CSS marginpaddingborder来表示空格和边框,而不是非中断空格或分隔符组件。它会使你的标记不必要地膨胀并且维护不友好。