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

时间:2021-11-15 19:59:37

In a JSF dataTable I want to display the row index next to the rows... like:

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

Column A    Column B
1           xxx
2           yyy

I thought that I could use an implicit el variable like #{rowIndex} but this is not working.

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

A solution I found is to create a binding for the data table and use the binding like:

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

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

but this solution is complex and doesn't work well when I have many nested dataTables in a page.

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

Any ideas on how to solve this in a better way?

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

5 个解决方案

#1


16  

The existing solution does not strike me as a bad one. The rowIndex should work in nested tables so long as you're referencing the model of the nested table.

现有的解决方案并不会让我感觉不好。只要您引用嵌套表的模型,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>

Sample model:

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();
    }

}

Nesting dataTables should generally be avoided - if you're not careful (e.g. make them children of a form), this can lead to a O(N^2) pass over the table children for each phase of the lifecycle on a submit (and there are 6 phases in the lifecycle).

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


For something that is external to the model, you could use a simple counter in a managed bean:

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

public class RowCounter implements Serializable {

    private transient int row = 0;

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

}

Config:

<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>

View:

<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>

This works because the bean is request-scope and bound to a read-only control outside a form. It would not work in a nested dataTable unless you wanted the row counter to be global to the view. But then, I'm not convinced that the row index should be a function of the view.

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

For a nested dataTable, you would be better off providing the row index from the row bean. It gives you more control if you decide to do things like pagination over data sets too.

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

#2


20  

This solution was posted by Jamie Williams on CodeRanch. He says it works with Tomahawk. I'm using primefaces, which also supports it.

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

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

#3


6  

In RichFaces there's a solution similar to Brent's:

在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>

#4


2  

This worked form me

这对我有用

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

#5


2  

I simply depend on list and position of var on this list:

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

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

#1


16  

The existing solution does not strike me as a bad one. The rowIndex should work in nested tables so long as you're referencing the model of the nested table.

现有的解决方案并不会让我感觉不好。只要您引用嵌套表的模型,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>

Sample model:

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();
    }

}

Nesting dataTables should generally be avoided - if you're not careful (e.g. make them children of a form), this can lead to a O(N^2) pass over the table children for each phase of the lifecycle on a submit (and there are 6 phases in the lifecycle).

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


For something that is external to the model, you could use a simple counter in a managed bean:

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

public class RowCounter implements Serializable {

    private transient int row = 0;

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

}

Config:

<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>

View:

<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>

This works because the bean is request-scope and bound to a read-only control outside a form. It would not work in a nested dataTable unless you wanted the row counter to be global to the view. But then, I'm not convinced that the row index should be a function of the view.

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

For a nested dataTable, you would be better off providing the row index from the row bean. It gives you more control if you decide to do things like pagination over data sets too.

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

#2


20  

This solution was posted by Jamie Williams on CodeRanch. He says it works with Tomahawk. I'm using primefaces, which also supports it.

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

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

#3


6  

In RichFaces there's a solution similar to Brent's:

在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>

#4


2  

This worked form me

这对我有用

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

#5


2  

I simply depend on list and position of var on this list:

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

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