PrimeFaces DataTable 在筛选时不会更新



我是PrimeFaces和JSF的新手。

我需要使用"包含"匹配模式过滤表。当数据是静态的时,它工作正常,但是当数据更改时,视图不会更新,并且仍然显示旧数据。当用户更改筛选器时,它会更新。如果未应用过滤器,则工作正常。

你有什么建议吗?

我发布了代码,灵感来自PrimeFaces 6展示。这是一个显示两列表的页面和一个为该表加载新数据的按钮

谢谢,任何帮助将不胜感激

<!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:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui">
<h:head >
Primefaces Data Table Test
</h:head>
<h:body>
<h:form>
<p:dataTable var="car" value="#{dtCar.cars}" widgetVar="carsTable"
emptyMessage="No cars found with given criteria"
filteredValue="#{dtCar.filteredCars}">

<p:column filterBy="#{car.model}" headerText="Model"
footerText="contains" filterMatchMode="contains">
<h:outputText value="#{car.model}" />
</p:column>
<p:column filterBy="#{car.color}" headerText="Color"
footerText="contains" filterMatchMode="contains">
<h:outputText value="#{car.color}" />
</p:column>
</p:dataTable>
<h:commandButton id="myButton" value="Load" action="#{dtCar.loadNewCars()}"/>
</h:form>
</h:body>
</html>

这是憨豆.java

package it.caditech.testtable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ManagedBean(name = "dtCar")
@ViewScoped
public class CarBean {
private List<Car> cars;
private List<Car> filteredCars;
public CarBean() {
setCars(new ArrayList<Car>());
getCars().add(new Car("myModel", "blu"));
getCars().add(new Car("punto", "blu"));
getCars().add(new Car("doblo", "grigio"));
getCars().add(new Car("smart", "blu"));
getCars().add(new Car("twingo", "rosso"));
getCars().add(new Car("twingo", "bianco"));
getCars().add(new Car("doblo", "blu"));
// add more cars
}
// getter setter
public List<Car> getCars() {
return cars;
}
public void setCars(List<Car> cars) {
this.cars = cars;
}
public List<Car> getFilteredCars() {
return filteredCars;
}
public void setFilteredCars(List<Car> filteredCars) {
this.filteredCars = filteredCars;
}
public String loadNewCars() {
if (getCars().get(0).getModel().equals("myModel")) {
getCars().clear();
getCars().add(new Car("gt", "giallo"));
getCars().add(new Car("scirocco", "azzurro"));
getCars().add(new Car("duna", "giallo"));
getCars().add(new Car("diablo", "griggio"));
getCars().add(new Car("cayenne", "rosso"));
getCars().add(new Car("aygo", "azzurro"));
setFilteredCars(null);
}
else {
getCars().clear();
getCars().add(new Car("myModel", "blu"));
getCars().add(new Car("punto", "blu"));
getCars().add(new Car("doblo", "grigio"));
getCars().add(new Car("smart", "blu"));
getCars().add(new Car("twingo", "rosso"));
getCars().add(new Car("twingo", "bianco"));
getCars().add(new Car("doblo", "blu"));
setFilteredCars(null);
}
return null;
}
}

这是汽车.java

package it.caditech.testtable;
public class Car {
private String model;
private String color;
public Car(String m, String c) {
model = m;
color = c;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}

正如@Kukeltje所建议的,我切换到懒惰模型,它工作得很好。我遵循了Primefaces Showcase https://www.primefaces.org/showcase/ui/data/datatable/lazy.xhtml 中的例子 对于惰性模型,我想分页器必须设置为 true,否则我的示例不起作用。

这是 pagina1 的新版本.xhtml

xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui">
<h:head >
Primefaces Data Table Test
</h:head>
<h:body>
<h:form id="form">
<p:dataTable id="dt" var="car" value="#{dtCar.lazyModel}" lazy="true" paginator="true" rows="2">
<p:column headerText="Id">
<h:outputText value="#{car.id}" />
</p:column>
<p:column filterBy="#{car.model}" headerText="Model">
<h:outputText value="#{car.model}" />
</p:column>
<p:column filterBy="#{car.color}" headerText="Color">
<h:outputText value="#{car.color}"/>
</p:column>
</p:dataTable>
<h:commandButton id="myButton" value="Load" action="#{dtCar.loadNewCars()}"/>
</h:form>
</h:body>
</html>

这是CarBean.java

package it.caditech.testtable;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.model.LazyDataModel;
@ManagedBean(name = "dtCar")
@ViewScoped
public class CarBean {
private LazyDataModel<Car> lazyModel;
@PostConstruct
public void init() {
lazyModel = new LazyCarDataModel();
}
public LazyDataModel<Car> getLazyModel() {
return lazyModel;
}
public String loadNewCars() {
((LazyCarDataModel) lazyModel).loadNewCars();
return null;
}
}

这是最重要的部分,LazyCarDataModel

package it.caditech.testtable;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
public class LazyCarDataModel extends LazyDataModel<Car> {
private List<Car> datasource = new ArrayList<>();
public LazyCarDataModel() {
loadNewCars();
}
@Override
public Car getRowData(String rowKey) {
for (Car car : datasource) {
if (car.getId().equals(rowKey)) {
return car;
}
}
return null;
}
@Override
public Object getRowKey(Car car) {
return car.getId();
}
@Override
public List<Car> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
List<Car> data = new ArrayList<Car>();
// filter
for (Car car : datasource) {
boolean match = true;
if (filters != null) {
for (Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
try {
String filterProperty = it.next();
Object filterValue = filters.get(filterProperty);
BeanInfo info = Introspector.getBeanInfo(Car.class);
String fieldValue = null;
for (PropertyDescriptor p : info.getPropertyDescriptors()) {
if (p.getName().equals(filterProperty)) {
fieldValue = (String) p.getReadMethod().invoke(car, new Object[0]);
}
}
// String fieldValue = String.valueOf(car.getClass().getField(filterProperty).get(car));
if (filterValue == null || fieldValue.contains(filterValue.toString())) {
match = true;
}
else {
match = false;
break;
}
}
catch (Exception e) {
match = false;
}
}
}
if (match) {
data.add(car);
}
}
// rowCount
int dataSize = data.size();
setRowCount(dataSize);
// paginate
if (dataSize > pageSize) {
try {
return data.subList(first, first + pageSize);
}
catch (IndexOutOfBoundsException e) {
return data.subList(first, first + dataSize % pageSize);
}
}
else {
return data;
}
}
protected void loadNewCars() {
if (datasource.isEmpty() || datasource.get(0).getModel().equals("myModel")) {
datasource.clear();
datasource.add(new Car("1", "gt", "giallo"));
datasource.add(new Car("2", "scirocco", "azzurro"));
datasource.add(new Car("3", "duna", "giallo"));
datasource.add(new Car("4", "diablo", "griggio"));
datasource.add(new Car("5", "cayenne", "rosso"));
datasource.add(new Car("6", "aygo", "azzurro"));
}
else {
datasource.clear();
datasource.add(new Car("7", "myModel", "blu"));
datasource.add(new Car("8", "punto", "blu"));
datasource.add(new Car("9", "doblo", "grigio"));
datasource.add(new Car("10", "smart", "blu"));
datasource.add(new Car("11", "twingo", "rosso"));
datasource.add(new Car("12", "twingo", "bianco"));
datasource.add(new Car("13", "twing", "rosa"));
datasource.add(new Car("14", "twist", "frizzante"));
datasource.add(new Car("15", "twelf", "rose"));
datasource.add(new Car("16", "twang", "riga"));
datasource.add(new Car("17", "doblo", "blu"));
}
}
}

我想可以省略汽车 Id 属性和方法 getRowData() 和 getRowKey(),因为在这种情况下我不需要选择处理。

试试这个:

<p:dataTable id="yourDataTable" var="car"...
<p:poll interval="3" update="yourDataTable" />

我认为您正在混合两种不同的功能,过滤数据并始终显示更新的数据。对于第二种情况,您有一些选择。您可以侦听某个事件,然后更新数据,或者您可以一直询问传入的新数据,例如jMarcel的示例。

检查您的事务是否并发。 使用相同的事务。

最新更新