我一直在搜索如何使用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=" #{entry.key}"/> </h:column>
<h:dataTable value="#{entry.value}" var="foo">
<h:column><h:outputText value="  " /></h:column>
<h:column><h:outputText value=" #{foo}" /></h:column>
</h:dataTable>
<p:separator></p:separator>
</c:forEach>
但是,结果略有不同,因为第一个字母在第一个记录的上方显示一行,而不是显示在与值列表中的第一个记录相同的行中。
目前的结果:
A
Apple
Arpa
Adverb
_________________
B
Background
Ball
Ballad
...
干杯
答案 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 margin
,padding
和border
来表示空格和边框,而不是非中断空格或分隔符组件。它会使你的标记不必要地膨胀并且维护不友好。