使用带有liveScroll的primefaces dataTable和一个惰性数据模型时,我有一些意想不到的行为。让我先说明一下这个例子,以便说明存在哪种问题。
我创建了一个小方法展示代码的小替代品。这是页面:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui">
<h:head />
<body>
<h:form id="form" style="width:300px;height:300px">
<p:dataTable id="carTable" var="car" value="#{carBean.carTableModel}" scrollable="true" lazy="true"
scrollHeight="200" scrollRows="10" liveScroll="true" rowKey="#{car.id}">
<p:column headerText="Id">
<h:outputText value="#{car.id}" />
</p:column>
<p:column headerText="Brand">
<h:outputText value="#{car.brand}" />
</p:column>
<p:column headerText="Action">
<h:commandButton value="Go!" action="#{carBean.go(car)}" update="goneCar" />
</p:column>
</p:dataTable>
<h:outputText id="goneCar" value="Last car gone: #{carBean.goneCar.id} #{carBean.goneCar.brand}" />
</h:form>
</body>
</html>
接下来是carBean支持bean代码。保持真的很简单。方法调用日志是抽象的。
@ManagedBean(name = "carBean")
@ViewScoped
public class CarBean implements Serializable {
private final static String[] BRANDS = {"BMW", "Mercedes", "Volvo",
"Audi", "Renault", "Fiat", "Volkswagen", "Honda", "Jaguar", "Ford"};
private Car goneCar;
private LazyCarDataModel carTableModel;
public CarBean() {
Car[] cars = new Car[200];
for (int i = 0; i < 200; i++) {
cars[i] = new Car(i, BRANDS[(int) (Math.random() * 10)]);
}
carTableModel = new LazyCarDataModel(cars);
}
public LazyCarDataModel getCarTableModel() {
return carTableModel;
}
public void go(Car car) {
log("go with " + car.getId());
goneCar = car;
}
public Car getGoneCar() {
return goneCar;
}
}
最后是LazyCarDataModel类。我添加了一些日志记录(摘要)来解释我的行为。看到我添加了getRowCount,它没有添加到primefaces手册中。如果没有添加,我根本看不到任何结果。
public class LazyCarDataModel extends LazyDataModel<Car> {
private Car[] datasource;
public LazyCarDataModel(Car[] datasource) {
this.datasource = datasource;
}
@Override
public int getRowCount() {
log("getRowCount");
return datasource.length;
}
@Override
public Car getRowData(String rowKey) {
log("getRowData " + rowKey);
return datasource[Integer.parseInt(rowKey)];
}
@Override
public Object getRowKey(Car car) {
log("getRowKey: "+car.getId());
return car.getId();
}
@Override
public List<Car> load(int first, int pageSize, String sortField,
SortOrder sortOrder, Map<String, Object> filters) {
int last = Math.min(first + pageSize, datasource.length);
log("refresh page " + first + " " + pageSize);
return Arrays.asList(Arrays.copyOfRange(datasource, first, last));
}
}
首次获取表格时,我看到一个包含10个项目的表格,由于视口较小,因此并未全部显示。以下是我的日志记录:
refresh page 0 10
getRowCount
getRowCount
接下来我点击第一个Go!按钮。我看到以下内容,其中getRowCount的次数被称为困扰我但是&#39;去0&#39;是正确的,但是这里不需要刷新页面0 10。
getRowCount
getRowCount
getRowCount
go with 0
refresh page 0 10
getRowCount
getRowCount
我滚动到表格中的最后一个元素,然后加载了10个项目的下一页。
refresh page 10 10
看起来不错。现在我点击按钮Go! id为== 6的行。这是在日志记录中:
getRowCount
getRowCount
getRowCount
go with 16
refresh page 0 10
getRowCount
getRowCount
这是错误的。使用16应该已经使用6.现在它还加载0长度== 10的项目,再次是第一页。现在再次单击相同按钮会显示:
getRowCount
getRowCount
getRowCount
go with 6
refresh page 0 10
getRowCount
getRowCount
哪个好,但刷新效率不高。同样错误的是,该表现在显示行0到9然后再到0再到9?
有人能解释一下我的代码中有什么问题吗?我使用primefaces-5.2。如何以可靠的方式使用此livescroll和lazy(分页)模型?
非常感谢!