Vaadin 8 网格排序在使用 DataProvider 时不起作用
Vaadin 8 Grid sorting doesn't work when using DataProvider
在 Vaadin 8 中,对 Grid 行进行排序就像单击列一样简单 header。如 here 所述,这会在升序和降序排序之间切换列。这在通过 grid.setItems()
方法填充网格时有效。
但是,当使用 DataProvider
作为网格数据源时,单击列 header 不会对行进行排序。
有关于 here 用 DataProvider
描述的排序顺序的文档,但在有多个排序要求时处理排序顺序。
是否有一种简单的方法可以简单地使用网格在填充 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");
在 Vaadin 8 中,对 Grid 行进行排序就像单击列一样简单 header。如 here 所述,这会在升序和降序排序之间切换列。这在通过 grid.setItems()
方法填充网格时有效。
但是,当使用 DataProvider
作为网格数据源时,单击列 header 不会对行进行排序。
有关于 here 用 DataProvider
描述的排序顺序的文档,但在有多个排序要求时处理排序顺序。
是否有一种简单的方法可以简单地使用网格在填充 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");