我只是在展示代码中为“
DataTable – Lazy Loading”启用了多个排序
datatableLazy.xhtml
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui" xmlns:ui="http://java.sun.com/jsf/facelets"> <h:head> <title>CarDataTable</title> </h:head> <h:body> <h:form id="form"> <p:dataTable var="car" value="#{tableBean.lazyModel}" paginator="true" rows="10" paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PrevIoUsPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" rowsPerPageTemplate="5,10,15" id="carTable" lazy="true" sortMode="multiple"> <p:ajax event="rowSelect" listener="#{tableBean.onRowSelect}" update=":form:display" oncomplete="carDialog.show()" /> <p:column headerText="Model" sortBy="#{car.model}" filterBy="#{car.model}"> <h:outputText value="#{car.model}" /> </p:column> <p:column headerText="Year" sortBy="#{car.year}" filterBy="#{car.year}"> <h:outputText value="#{car.year}" /> </p:column> <p:column headerText="Manufacturer" sortBy="#{car.manufacturer}" filterBy="#{car.manufacturer}"> <h:outputText value="#{car.manufacturer}" /> </p:column> <p:column headerText="Color" sortBy="#{car.color}" filterBy="#{car.color}"> <h:outputText value="#{car.color}" /> </p:column> </p:dataTable> </h:form> </h:body> </html>
TableBean.java
package com.solartis.primefaces.sample; import java.util.ArrayList; import java.util.List; import java.util.UUID; import javax.faces.bean.ManagedBean; import org.primefaces.model.LazyDataModel; @ManagedBean public class TableBean { private LazyDataModel<Car> lazyModel; private Car selectedCar; private List<Car> cars = new ArrayList<Car>(); private final static String[] colors; private final static String[] manufacturers; static { colors = new String[10]; colors[0] = "Black"; colors[1] = "White"; colors[2] = "Green"; colors[3] = "Red"; colors[4] = "Blue"; colors[5] = "Orange"; colors[6] = "Silver"; colors[7] = "Yellow"; colors[8] = "Brown"; colors[9] = "Maroon"; manufacturers = new String[10]; manufacturers[0] = "Mercedes"; manufacturers[1] = "BMW"; manufacturers[2] = "Volvo"; manufacturers[3] = "Audi"; manufacturers[4] = "Renault"; manufacturers[5] = "Opel"; manufacturers[6] = "Volkswagen"; manufacturers[7] = "Chrysler"; manufacturers[8] = "Ferrari"; manufacturers[9] = "Ford"; } public TableBean() { populateRandomCars(cars,50); lazyModel = new LazyCarDataModel(cars); } public Car getSelectedCar() { return selectedCar; } public void setSelectedCar(Car selectedCar) { this.selectedCar = selectedCar; } public LazyDataModel<Car> getLazyModel() { return lazyModel; } private void populateRandomCars(List<Car> list,int size) { for (int i = 0; i < size; i++) { list.add(new Car(getRandomModel(),getRandomYear(),getRandomManufacturer(),getRandomColor())); } } private String getRandomColor() { return colors[(int) (Math.random() * 10)]; } private String getRandomManufacturer() { return manufacturers[(int) (Math.random() * 10)]; } private int getRandomYear() { return (int) (Math.random() * 50 + 1960); } private String getRandomModel() { return UUID.randomUUID().toString().substring(0,8); } }
LazyCarDataModel.java
package com.solartis.primefaces.sample; import java.util.ArrayList; /** * Dummy implementation of LazyDataModel that uses a list to mimic a real datasource like a database. */ public class LazyCarDataModel extends LazyDataModel<Car> { private List<Car> datasource; public LazyCarDataModel(List<Car> datasource) { this.datasource = datasource; } @Override public Car getRowData(String rowKey) { for(Car car : datasource) { if(car.getModel().equals(rowKey)) return car; } return null; } @Override public void setRowIndex(int rowIndex) { if (rowIndex == -1 || getPageSize() == 0) { super.setRowIndex(-1); } else super.setRowIndex(rowIndex % getPageSize()); } @Override public Object getRowKey(Car car) { return car.getModel(); } @Override public List<Car> load(int first,int pageSize,List<SortMeta> multiSortMeta,Map<String,String> filters) { System.out.println("\nTHE INPUT PARAMETER VALUE OF LOAD METHOD : \t"+"first=" + first + ",pagesize=" + pageSize + ",multiSortMeta=" + multiSortMeta + " filter:" + filters); System.out.println("\nTHE MULTISORTMeta CONTENT : \t"); if (multiSortMeta != null) { for (SortMeta sortMeta : multiSortMeta) { System.out.println("SORTFIELD:" +sortMeta.getSortField()); System.out.println("SORTORDER:" +sortMeta.getSortOrder()); System.out.println("SORTFUNCTION:" +sortMeta.getSortFunction()); System.out.println("COLUMN:" +sortMeta.getColumn()); System.out.println("CLASS:" +sortMeta.getClass()); } } List<Car> data = new ArrayList<Car>(); //filter for(Car car : datasource) { boolean match = true; for(Iterator<String> it = filters.keySet().iterator(); it.hasNext();) { try { String filterProperty = it.next(); String filterValue = filters.get(filterProperty); String fieldValue = String.valueOf(car.getClass(). getField(filterProperty).get(car)); if(filterValue == null || fieldValue.startsWith(filterValue)) { match = true; } else { match = false; break; } } catch(Exception e) { match = false; } } if(match) { data.add(car); } } //rowCount int dataSize = data.size(); this.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; } } }
它很好用,除非我用多列排序分页,带有List< SortMeta>的load()方法.没有给我当前排序到其他页面的列详细信息,不像使用String sortField的load()方法,SortOrder sortOrder给出了那些排序细节.
例如:
>点击“制造商”中的排序箭头,然后按住Ctrl键点击“年份”的排序箭头
>你会得到load()方法的排序列详细信息(我在load方法中打印了输入参数值).
>现在,做分页.这里load()方法无法给出排序列的详细信息
>不仅是分页,如果在单击排序列后输入列过滤器值,则存在同样的问题
我怎样才能解决这个问题?
解决方法
我暂时解决了这个问题……
有一个sessioncoped托管bean用于存储排序列的详细信息,以便在分页期间进入load(),
喜欢:-
有一个sessioncoped托管bean用于存储排序列的详细信息,以便在分页期间进入load(),
喜欢:-
@ManagedBean @SessionScoped public class StoreSortColumnDetail implements Serializable{ /** holds multisort values**/ private List<SortMeta> mMultiSortMeta; public List<SortMeta> getMultiSortMeta() { return mMultiSortMeta; } public void setMultiSortMeta(List<SortMeta> multiSortMeta) { mMultiSortMeta = multiSortMeta; } public void clearMultiSortMeta() { if(this.mMultiSortMeta != null) this.mMultiSortMeta.clear(); } }
并在load()中使用它,如下所示:
@Override public List<Car> load(int first,String> filters) { /** Instance to the SessionScoped scoped StoreSortColumnDetail managed bean*/ @ManagedProperty(value="#{StoreSortColumnDetail }") private StoreSortColumnDetail storeSortColumnDetail ; public void setStoreSortColumnDetail (StoreSortColumnDetail sortColumnDetail ) { this.storeSortColumnDetail = sortColumnDetail ; } /** to hold the handled sort column detail**/ List<SortMeta> handledMultiSortMeta = new ArrayList<SortMeta>(); /*Here starts the multisortMeta handling process*/ /** check for List<SortMeta> for null**/ if(multiSortMeta != null ) { /** updates StoreSortColumnDetail's List<SortMeta> with Load()'s List<SortMeta>**/ storeSortColumnDetail.setMultiSortMeta(multiSortMeta); handledMultiSortMeta = multiSortMeta; } /** check for List<SortMeta> for notnull **/ else if (multiSortMeta == null) { /**assigns Load()'s List<SortMeta> with StoreSortColumnDetail's List<SortMeta>**/ handledMultiSortMeta = storeSortColumnDetail.getMultiSortMeta(); } /*Now u have handled multisortMeta from load()... and u can process now from handledMultiSortMeta*/ }
我希望你知道我是如何处理的,如果不是亲密的我……但这是一种暂时的方式,需要通过primefaces方式处理它…