如何在 JSF 数据表中显示行索引
Posted
技术标签:
【中文标题】如何在 JSF 数据表中显示行索引【英文标题】:How to display the row index in a JSF datatable 【发布时间】:2010-09-22 19:46:39 【问题描述】:在 JSF 数据表中,我想在行旁边显示行索引...例如:
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>
但是当我在一个页面中有许多嵌套的数据表时,这个解决方案很复杂并且效果不佳。
关于如何以更好的方式解决此问题的任何想法?
【问题讨论】:
见 [***.com/questions/14633008/….这个答案比下面的答案更新 - 也很简短。 这能回答你的问题吗? JSF 2 dataTable row index without dataModel 【参考方案1】:此解决方案由 Jamie Williams 在CodeRanch 上发布。他说它适用于战斧。我正在使用 primefaces,它也支持它。
<t:dataTable rowIndexVar="row" value="#someBean.value">
<h:column>
<h:outputText value="#row + 1"/>
</h:column>
</t:dataTable>
【讨论】:
Ursula 的评论:“感谢您使用 rowIndexVar 的解决方案。我正在使用 JSF 1.2 和 myFaces,它只能在 row+1<h:outputText value="#row+1"/>
没有空格的情况下工作”【参考方案2】:
现有的解决方案在我看来并不坏。只要您引用嵌套表的模型,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 中不起作用。但是,我不相信行索引应该是视图的函数。
对于嵌套数据表,最好从行 bean 提供行索引。如果您也决定对数据集进行分页等操作,它会给您更多的控制权。
【讨论】:
不错。为什么从 JSF 数据表中获取行号这么复杂?维护 JSF 的人是否憎恨所有其他开发人员,并且他们故意让 JSF 变得困难?【参考方案3】:在 RichFaces 中有一个类似于 Brent 的解决方案:
<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】:这对我有用
<h:dataTable var="item" value="#controller.items">
<h:column>#controller.items.indexOf(item)</h:column>
<h:column>value</h:column>
</h:dataTable>
【讨论】:
这个解决方案有一个问题:它只有在你有一个合适的equals方法时才有效,否则你总是会得到-1。而且每个对象都必须不同。如果您在数据结构中有多个相等对象,您将始终获得第一个位置(如果它是一个列表)。【参考方案5】:我只是依赖列表和 var 在这个列表中的位置:
<h:column>
<f:facet name="header">#</f:facet>
#bean.listValue.indexOf(varObject)+1
</h:column>
【讨论】:
【参考方案6】:自 JSF 2.0(2009 年引入)以来,视图中的当前 UIComponent
实例可通过隐式 EL 变量 #component
获得。另见What exactly is #component in EL?
<h:dataTable>
标签由实现NamingContainer
的UIData
组件支持。因此,在<h:dataTable>
上下文中的任何位置使用#component.namingContainer
将为您提供具体的UIData
实例,通常具有htmlDataTable
类的风格。
<h:dataTable value="#['one', 'two', 'three']" var="item">
<h:column>This is the `UIData` component: #component.namingContainer</h:column>
</h:dataTable>
jakarta.faces.component.html.HtmlDataTable@cafebabe jakarta.faces.component.html.HtmlDataTable@cafebabe jakarta.faces.component.html.HtmlDataTable@cafebabe
UIData
类又具有getRowIndex()
方法,所以这就足够了:
<h:dataTable value="#['one', 'two', 'three']" var="item">
<h:column>Row index: #component.namingContainer.rowIndex + 1</h:column>
</h:dataTable>
1 2 3
请注意它是从零开始的,因此是 + 1
。
不需要binding
或第 3 方标签或任何自定义支持 bean 逻辑。
【讨论】:
以上是关于如何在 JSF 数据表中显示行索引的主要内容,如果未能解决你的问题,请参考以下文章