sorting - RichFaces 扩展表数据模型 : sorting columns retrieves all rows

标签 sorting jsf datatable richfaces

我们使用 ExtendedTableDataModel 进行分页。这样做是为了使用 Hibernate 检索一组结果,并在请求另一个页面时加载下一组结果。

一切正常,但如果我们在 rich:dataTable 中使用 rich:column sortBy 对列进行排序,则 RichFaces 会尝试加载所有行。我们可以在调试为自定义 DataProvider 制作的 getItemsByRange 时看到这一点。单击一次排序后,RichFaces 将继续从数据库中检索所有行。这当然不是我们想要的。我们希望使用此解决方案来最大限度地减少数据流量和加载时间。

我们使用 Richfaces 3.3.2。有人有可能的解决方案或解决方法吗?

最佳答案

我们遇到了同样的问题,这是我们的解决方案。我不完全确定我粘贴的整个代码是否相关,但应该是

public class PagingExtendedTableDataModel<T> extends ExtendedDataModel implements
        Serializable, Modifiable {

    private DataProvider dataProvider;
    private Object rowKey;
    private List wrappedKeys;
    private Map wrappedData;
    private Integer rowCount;
    private Integer rowIndex;
    private List<FilterField> filterFields;
    private List<SortField2> sortFields;

    public PagingExtendedTableDataModel(DataProvider<T> dataProvider) {
        wrappedKeys = null;
        wrappedData = new HashMap();
        rowCount = null;
        rowIndex = Integer.valueOf(-1);
        rowKey = null;

        this.dataProvider = dataProvider;
    }

    public Object getRowKey() {
        return rowKey;
    }

    public void setRowKey(Object key) {
        rowKey = key;
    }

    @SuppressWarnings("unchecked")
    public void walk(FacesContext context, DataVisitor visitor, Range range,
            Object argument) throws IOException {

        int rowC = getRowCount();
        int firstRow = ((SequenceRange) range).getFirstRow();
        int numberOfRows = ((SequenceRange) range).getRows();
        if (numberOfRows <= 0) {
            numberOfRows = rowC;
        }

        if (wrappedKeys != null) {
            Object key;
            for (Iterator it = wrappedKeys.iterator(); it.hasNext();
                visitor.process(context, key, argument)) {

                key = it.next();
                setRowKey(key);
            }

        } else {
            wrappedKeys = new ArrayList();
            int endRow = firstRow + numberOfRows;
            if (endRow > rowC) {
                endRow = rowC;
            }

            if (dataProvider instanceof Sortable2) {
                ((Sortable2) dataProvider).setSortFields(sortFields);
            }

            if (dataProvider instanceof Filterable) {
                ((Filterable) dataProvider).setFilterFields(filterFields);
            }

            Object key;
            for (Iterator it = loadData(firstRow, endRow).iterator(); it.hasNext();
                visitor.process(context, key, argument)) {

                Object item = it.next();
                key = getKey(item);
                wrappedKeys.add(key);
                wrappedData.put(key, item);
            }

        }
    }

    protected List loadData(int startRow, int endRow) {
        if (startRow < 0) {
            startRow = 0;
            throw new IllegalArgumentException((new StringBuilder()).append(
                    "Illegal start index value: ").append(startRow).toString());
        }
        int rowCount = getRowCount();
        if (endRow > rowCount) {
            endRow = rowCount;
            throw new IllegalArgumentException((new StringBuilder()).append(
                    "Illegal end index value: ").append(endRow).toString());
        }

        return dataProvider.getItemsByRange(startRow, endRow);
    }

    public int getRowCount() {
        if (rowCount == null) {
            rowCount = new Integer(dataProvider.getRowCount());
        } else {
            return rowCount.intValue();
        }

        return rowCount.intValue();
    }

    public Object getRowData() {
        if (rowKey == null) {
            return null;
        }

        return getObjectByKey(rowKey);
    }

    @SuppressWarnings("unchecked")
    public Object getKey(Object o) {
        return dataProvider.getKey(o);
    }

    @SuppressWarnings("unchecked")
    public Object getObjectByKey(Object key) {
        Object t = wrappedData.get(key);
        if (t == null) {
            t = dataProvider.getItemByKey(key);
            wrappedData.put(key, t);
        }
        return t;
    }

    public int getRowIndex() {
        return rowIndex.intValue();
    }

    public void setRowIndex(int rowIndex) {
        this.rowIndex = Integer.valueOf(rowIndex);
    }

    public Object getWrappedData() {
        throw new UnsupportedOperationException();
    }

    public void setWrappedData(Object data) {
        throw new UnsupportedOperationException();
    }

    public boolean isRowAvailable() {
        return getRowData() != null;
    }

    public void reset() {
        wrappedKeys = null;
        wrappedData.clear();
        rowCount = null;
        rowIndex = Integer.valueOf(-1);
        rowKey = null;
    }

    public DataProvider getDataProvider() {
        return dataProvider;
    }

    public void setDataProvider(DataProvider dataProvider) {
        this.dataProvider = dataProvider;
    }

    @Override
    public void modify(List<FilterField> filterFields, List<SortField2> sortFields) {
        this.filterFields = filterFields;
        this.sortFields = sortFields;

        reset();
    }
}

而且您还需要一个自定义的DataProvider

public class PagingDataProvider implements DataProvider<BeanDisplay>,
      Sortable2, Filterable 

在方法 getItemsByRange 中,使您的查询仅加载有限数量的记录。所有其他方法应该很容易实现(我没有粘贴我们的代码,因为它充满了非常具体的代码,这是不相关的)

您可以按如下方式构建数据模型:

new PagingExtendedTableDataModel<BeanDisplay>(new PagingDataProvider());

关于sorting - RichFaces 扩展表数据模型 : sorting columns retrieves all rows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3707897/

相关文章:

c++ - 在 cpp 中使用带有 std::vector 的字符串长度对字符串数组进行排序

excel - 对包含合并单元格的 Excel 表进行排序

C# List<T> OrderBy float 成员

jquery - 找不到文件 'dataTables/jquery.dataTables' Rails 4

javascript - 使用 Greasemonkey 修改 Craigslist 的默认搜索结果排序?

java - 将要通过字段注入(inject) (CDI) 初始化的测试字段

javascript - jsf.ajax.request 是否忽略了 onevent 选项?

jsp - JSF 1.x 通用异常处理

c# - 在数据集中寻找字段 C#

c# - 如何从数据表中获取最高值?