在JSF + Facelets中迭代HashMap.values()

Mat*_*inn 5 java datatable jsf

我正在使用JSF/Facelets,我正在尝试迭代一些我保留在HashMap中的Document对象(自定义对象).加载页面时,我收到错误"类型java.util.HashMap $ Values"中找不到"属性'名称".这是我的支持bean中的内容:

private Map<String, Document> documents = new HashMap<String, Document>();

public Collection<Document> getDocuments(){
    return documents.values();
}
Run Code Online (Sandbox Code Playgroud)

在我的xhtml页面中:

<h:dataTable id="documentTable"
    value="#{DocumentManager.allDocuments}"
    var="doc" rowClasses="list-row-odd, list-row-even"
    headerClass="table-header" styleClass="bordered">

    <h:column id="col_name">
         <f:facet name="header">Name</f:facet>
         ${doc.name}
    </h:column>
</h:dataTable>
Run Code Online (Sandbox Code Playgroud)

如果我将getDocuments函数更改为以下,它可以工作(意味着表显示没有错误),但我不知道为什么我需要将值放在JSF/Facelets页面的列表中才能正确显示.

public List<Document> getDocuments(){
    List<Document> rtrn = new ArrayList<Document>();
    for(Document doc : documents.values())
        rtrn.add(doc);
    return rtrn;
}
Run Code Online (Sandbox Code Playgroud)

我不应该能够迭代收藏吗?

bil*_*dev 9

好吧,事实证明,你不能只使用dataTable的任何类型的集合类型,并且有充分的理由.从MyFaces 1.2 Spec中,value属性必须是:

一个EL表达式,指定支持此表的数据模型.

EL表达式引用的值可以是任何类型.

  • 直接使用DataModel类型的值.
  • 型的阵列状参数Object[],java.util.List,java.sql.ResultSetjavax.servlet.jsp.jstl.sql.Result包裹在相应的DataModelthat知道如何在元件进行迭代.
  • 其他值作为单行包装在DataModel中.

特别注意无序集合,例如Set不受支持.因此,如果值表达式引用了这样的对象,那么该表将被视为仅包含一个元素 - 集合本身.

从HashSet.values()返回的Collection不是有序的,因此不受支持.如果是,您不知道表格中的行将以什么顺序输出,并且页面的刷新可以随机重新排序.不好.

您收到的错误是,从最后一段开始,它表示数据表将您的Collection视为行对象,而Collection没有"name"属性.