【问题标题】:Dynamically generate h:column based on list of hashmaps根据 hashmap 列表动态生成 h:column
【发布时间】:2016-06-05 07:45:59
【问题描述】:

在我的应用程序中,我想显示一个带有托管 bean 属性的 <h:dataTable>。目前,此表是从 List<Folder> 创建的。现在我想将Folder 更改为更动态的东西。那是因为如果我决定稍后添加另一个字段,我不想更改 Folder 类。我只需要在Map<String, Object> 中添加另一个条目,而不是在Folder 中引入一个新字段。

那么,是否可以将List<Map<String, Object>> 绑定到<h:dataTable>

【问题讨论】:

    标签: jsf dynamic jsf-2 datatable


    【解决方案1】:

    是否可以将 HashMaps 列表绑定到 jsf 组件 h:dataTable?

    只有在生成必要的<h:column> 标记和视图构建时间标记(例如 JSTL <c:forEach>)时才有可能。

    这是一个具体的启动示例,假设您的环境支持 EL 2.2:

    <h:dataTable value="#{bean.listOfMaps}" var="map">
        <c:forEach items="#{bean.listOfMaps[0].keySet().toArray()}" var="key">
            <h:column>
                #{map[key]}
            </h:column> 
        </c:forEach>
    </h:dataTable>
    

    (如果您的环境不支持 EL 2.2,您需要提供另一个 getter,它将映射键集返回为 String[]List&lt;String&gt;;还要记住 HashMap本质上是无序的,您可能希望使用LinkedHashMap 来维护插入顺序)

    当您使用早于 2.1.18 的 Mojarra 版本时,缺点是 #{bean} 必须是请求范围(而不是视图范围)。或者至少,&lt;c:forEach items&gt; 应该引用一个请求范围的 bean。否则,当视图范围尚不可用时,&lt;c:forEach&gt; 在视图构建期间运行时,将在每个 HTTP 请求上重新创建视图范围 bean。如果您绝对需要 &lt;h:dataTable&gt; 的视图范围 bean,那么您始终可以专门为 &lt;c:forEach items&gt; 创建一个单独的请求范围 bean。解决方案是升级到 Mojarra 2.1.18 或更高版本。有关一些背景信息,另请参阅JSTL in JSF2 Facelets... makes sense?

    诸如PrimeFaces 之类的JSF 组件库可能会提供一个&lt;x:columns&gt; 标记,这使得这更容易,例如&lt;p:dataTable&gt; with &lt;p:columns&gt;

    <p:dataTable value="#{bean.listOfMaps}" var="map">
        <p:columns value="#{bean.listOfMaps[0].keySet().toArray()}" var="key">
            #{map[key]}
        </p:columns>
    </p:dataTable>
    

    【讨论】:

    • 啊,这就是我想要的。唯一烦人的是我必须使用 forEach。我在某处读到,还可以为您自己的数据结构实现一些接口(不记得名称),以便 jsf 知道如何呈现它。这是可能的吗?还是我在那里搞错了?
    • 我认为你弄错了 :) 对于&lt;h:dataTable&gt;UIColumn 子级确实必须在视图构建期间填充。 &lt;c:forEach&gt; 是在视图构建期间运行的唯一可用迭代标记。
    猜你喜欢
    • 2022-07-22
    • 2013-09-21
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-11
    • 1970-01-01
    相关资源
    最近更新 更多