我是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;
}
}
答案 0 :(得分:3)
正如@Kukeltje建议我切换到lazyModel并且它工作得非常好。我按照Primefaces Showcase https://www.primefaces.org/showcase/ui/data/datatable/lazy.xhtml中的示例进行操作 使用懒惰模型我猜想必须将paginator设置为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()可以省略,因为在这种情况下我不需要选择处理。
答案 1 :(得分:0)
试试这个:
<p:dataTable id="yourDataTable" var="car"...
<p:poll interval="3" update="yourDataTable" />
答案 2 :(得分:0)
我认为您正在混合两种不同的功能,过滤数据并始终显示更新的数据。对于第二种情况,您可以选择一些选项。您可以收听某些事件然后更新数据,也可以随时询问传入的新数据,例如jMarcel的示例。
答案 3 :(得分:0)
检查您的交易是并发的。 使用同一笔交易。