Vaadin 8 网格排序在使用 DataProvider 时不起作用

Vaadin 8 Grid sorting doesn't work when using DataProvider

在 Vaadin 8 中,对 Grid 行进行排序就像单击列一样简单 header。如 here 所述,这会在升序和降序排序之间切换列。这在通过 grid.setItems() 方法填充网格时有效。

但是,当使用 DataProvider 作为网格数据源时,单击列 header 不会对行进行排序。

有关于 hereDataProvider 描述的排序顺序的文档,但在有多个排序要求时处理排序顺序。

是否有一种简单的方法可以简单地使用网格在填充 grid.setItems() 时与我们填充 grid.setDataProvider() 时显示的相同默认排序行为?

答案是否定的,否则没有多大意义。 grid.setItems 方法在内部创建一个 ListDataProvider ,它是一个内存数据提供者。因为它将所有数据保存在一个列表中,所以它可以使用比较器(来自网格列定义或提供给列表数据提供者)轻松地对数据进行排序。因此,Vaadin 只能在您可以将所有数据保存在内存中时帮助您进行排序。如果你有大量的行(例如一百万),这是低效的,因为你有很多内存和 CPU 消耗。这是您的自定义数据提供程序的用武之地。

DataProvider的想法是将数据检索委托给后端系统,例如数据库。例如,SQL 数据库允许在 SQL 查询中指定一个 "ORDER BY" 子句,您可以使用它通过后端对数据进行排序。假设您应用了正确的索引,数据库本身在资源消耗方面非常有效。

那么您的实际数据源是什么?也许您可以分享您目前所做的数据提供程序代码。

编辑

摘自ListDataProvider

@Override
public Stream<T> fetch(Query<T, SerializablePredicate<T>> query) {
    Stream<T> stream = getFilteredStream(query);

    Optional<Comparator<T>> comparing = Stream
            .of(query.getInMemorySorting(), sortOrder)
            .filter(c -> c != null)
            .reduce((c1, c2) -> c1.thenComparing(c2));

    if (comparing.isPresent()) {
        stream = stream.sorted(comparing.get());
    }

    return stream.skip(query.getOffset()).limit(query.getLimit());
}

@Override
public int size(Query<T, SerializablePredicate<T>> query) {
    return (int) getFilteredStream(query).count();
}

根据评论回答您的问题:是的,ListDataProvider 会按照您在其源代码中看到的那样进行排序。对于您的 SQL 数据库:是的,这是首选方式。

我遇到了同样的问题,我在 post

的评论中找到了解决方案

When creating new Grid<Foo>(), it's not the same as new Grid<Foo>(Foo.class).

The second one creates columns also with sortProperties based on provided class. When you define columns manualy, you should define also sortProperties.

grid.addColumn(Foo::getBar).setSortProperty("bar").setCaption("Bar");