如何在JSF数据表中显示行索引

时间:2008-11-18 08:07:38

标签: jsf datatable

在JSF dataTable中,我想显示行旁边的行索引......如:

Column A    Column B
1           xxx
2           yyy

我认为我可以使用像#{rowIndex}这样的隐式el变量,但这不起作用。

我找到的解决方案是为数据表创建绑定并使用如下的绑定:

<h:dataTable var="item" value="#{controller.items}" binding="#{controller.dataTable}">
    <h:column>#{controller.dataTable.rowIndex}</h:column>
    <h:column>value</h:column>
</h:dataTable>

但是当我在页面中有许多嵌套的dataTable时,这个解决方案很复杂并且效果不好。

关于如何以更好的方式解决这个问题的任何想法?

5 个答案:

答案 0 :(得分:23)

此解决方案由Jamie Williams在CodeRanch发布。他说这适用于战斧。我正在使用primefaces,它也支持它。

<t:dataTable rowIndexVar="row" value="#{someBean.value}">  
    <h:column>  
        <h:outputText value="#{row + 1}"/>  
    </h:column>  
</t:dataTable>

答案 1 :(得分:16)

现有的解决方案并不会让我感觉不好。只要您引用嵌套表的模型,rowIndex就应该在嵌套表中工作。

    <h:dataTable border="1" value="#{nestedDataModel}" var="nested">
        <h:column>
            <h:dataTable border="1" value="#{nested}" var="item">
                <h:column>
                    <h:outputText value="#{nested.rowIndex}" />
                </h:column>
                <h:column>
                    <h:outputText value="#{item}" />
                </h:column>
            </h:dataTable>
        </h:column>
    </h:dataTable>

样本模型:

public class NestedDataModel extends DataModel implements Serializable {

    private List<List<String>> nestedDataModel = populateModel();
    private int index;

    private List<List<String>> populateModel() {
        List<List<String>> list = new ArrayList<List<String>>();
        for(int x=0; x<3; x++) {
            List<String> nestedTableData = new ArrayList<String>();
            for(int y=0; y<3; y++) {
                nestedTableData.add("Foo x="+x+" y="+y);
            }
            list.add(nestedTableData);
        }
        return list;
    }

    @Override
    public int getRowCount() {
        return nestedDataModel.size();
    }

    @Override
    public Object getRowData() {
        List<String> list = nestedDataModel.get(index);
        return new ListDataModel(list);
    }

    @Override
    public int getRowIndex() {
        return index;
    }

    @Override
    public Object getWrappedData() {
        return nestedDataModel;
    }

    @Override
    public boolean isRowAvailable() {
        return index >= 0 && index < nestedDataModel.size();
    }

    @Override
    public void setRowIndex(int arg0) {
        index = arg0;
    }

    @Override
    public void setWrappedData(Object arg0) {
        throw new UnsupportedOperationException();
    }

}

通常应该避免嵌套数据表 - 如果你不小心(例如,让它们成为表单的子项),这可能导致在表生成周期的每个阶段对表子进行O(N ^ 2)传递。提交(生命周期中有6个阶段)。


对于模型外部的东西,您可以在托管bean中使用一个简单的计数器:

public class RowCounter implements Serializable {

    private transient int row = 0;

    public int getRow() {
        return ++row;
    }

}

配置:

<managed-bean>
    <managed-bean-name>rowCounter</managed-bean-name>
    <managed-bean-class>tablerows.RowCounter</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

查看:

<f:view>
    <h:dataTable border="1" value="#{tableDataBean.tableDataModel}"
        var="rowBean">
        <h:column>
            <h:outputText value="#{rowCounter.row}" />
        </h:column>
        <h:column>
            <h:outputText value="#{rowBean}" />
        </h:column>
    </h:dataTable>
</f:view>

这是有效的,因为bean是请求范围并绑定到表单外部的只读控件。它不适用于嵌套的dataTable,除非您希望行计数器对视图是全局的。但是,我不相信行索引应该是视图的函数。

对于嵌套的dataTable,最好从行bean中提供行索引。如果您决定对数据集进行分页等操作,它会为您提供更多控制。

答案 2 :(得分:7)

在RichFaces中,有一种类似于布伦特的解决方案:

<rich:dataTable value="#{backingBean.list}" var="v" rowKeyVar="index">
    <rich:column>
        <f:facet name="header">Index</f:facet>
        <h:outputText value="#{index + 1}" />
    </rich:column>
    <rich:column>
        <f:facet name="header">Name</f:facet>
        <h:outputText value="#{v.name}" />
    </rich:column>
</rich:dataTable>

答案 3 :(得分:3)

这就形成了我的作品

<h:dataTable var="item" value="#{controller.items}">
    <h:column>#{controller.items.indexOf(item)}</h:column>
    <h:column>value</h:column>
</h:dataTable>

答案 4 :(得分:3)

我只依赖于此列表中var的列表和位置:

<h:column>
          <f:facet name="header">#</f:facet>
          #{bean.listValue.indexOf(varObject)+1}
</h:column>