PrimeFaces DataTable在过滤后无法更新

时间:2017-07-05 13:45:38

标签: jsf primefaces

我是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;
  }
}

4 个答案:

答案 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)

检查您的交易是并发的。 使用同一笔交易。