[英]PrimeFaces DataTable doesn't update when filtered
我是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>
這是CarBean.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;
}
}
這是Car.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建議我切換到lazyModel並且它工作得非常好。 我按照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的示例。
檢查您的交易是否並發。 使用相同的交易。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.