在JSF dataTable中,我想显示行旁边的行索引...如:
Column A Column B
1 xxx
2 yyy
Run Code Online (Sandbox Code Playgroud)
我认为我可以使用像#{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>
Run Code Online (Sandbox Code Playgroud)
但是当我在页面中有许多嵌套的dataTable时,这个解决方案很复杂并且不能很好地工作.
关于如何以更好的方式解决这个问题的任何想法?
Bre*_*lay 24
这个解决方案由Jamie Williams在CodeRanch上发布.他说这适用于战斧.我正在使用primefaces,它也支持它.
<t:dataTable rowIndexVar="row" value="#{someBean.value}">
<h:column>
<h:outputText value="#{row + 1}"/>
</h:column>
</t:dataTable>
Run Code Online (Sandbox Code Playgroud)
McD*_*ell 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>
Run Code Online (Sandbox Code Playgroud)
样品型号:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
通常应该避免嵌套数据表 - 如果您不小心(例如,让它们成为表单的子项),这可能导致在提交的生命周期的每个阶段对表子项进行O(N ^ 2)传递(并且生命周期中有6个阶段).
对于模型外部的东西,您可以在托管bean中使用一个简单的计数器:
public class RowCounter implements Serializable {
private transient int row = 0;
public int getRow() {
return ++row;
}
}
Run Code Online (Sandbox Code Playgroud)
配置:
<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>
Run Code Online (Sandbox Code Playgroud)
视图:
<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>
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为bean是请求范围并绑定到表单外部的只读控件.它不适用于嵌套的dataTable,除非您希望行计数器对视图是全局的.但是,我不相信行索引应该是视图的函数.
对于嵌套的dataTable,最好从行bean中提供行索引.如果您决定对数据集进行分页等操作,它会为您提供更多控制.
在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>
Run Code Online (Sandbox Code Playgroud)