callback - Vaadin CallbackDataProvider 如何异步获取数据?

标签 callback vaadin-flow dataprovider vaadin-grid vaadin14

Vaadin 14.CallbackDataProvider。当服务缓慢且应答时间较长时,连接到 CallbackDataProvider 的网格会随着所有 UI 卡住。 一些例子:

import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.data.provider.CallbackDataProvider;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.router.RouteAlias;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

public class GridWithSortableColumnsView extends VerticalLayout {

    public GridWithSortableColumnsView() {
        addClassName("dialogwithgrid-view");
        setSizeFull();

        // prepare Data
        List<GridRow> gridRows = new LinkedList<>();
        for (int i = 0; i < 10000; i++) {
            gridRows.add(new GridRow(i, RandomStringUtils.randomAlphanumeric(10)));
        }

        CallbackDataProvider<GridRow, Void> dataProvider = new CallbackDataProvider<>(
                query -> {

                    // Slow service answer is here
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    Notification.show("Offset=" + query.getOffset() + " Limit=" + query.getLimit());
                    return gridRows.stream()
                            .sorted((o1, o2) -> StringUtils.compare(o1.getCol05(), o2.getCol05()))
                            .skip(query.getOffset())
                            .limit(query.getLimit());
                },
                query -> gridRows.size());

        Grid<GridRow> grid = new Grid<>();
        grid.setPageSize(10);
        grid.setSizeFull();
        grid.addColumn(GridRow::getId).setHeader("Id");
        grid.addColumn(GridRow::getCol05).setHeader("col05");
        grid.setDataProvider(dataProvider);

        add(grid);
    }


    @EqualsAndHashCode(onlyExplicitlyIncluded = true)
    @AllArgsConstructor
    @Getter
    @Setter
    public static class GridRow {
        @EqualsAndHashCode.Include
        private int id;
        private String col05;
    }

}

滚动此网格时, session 被锁定,所有 UI 组件都会卡住。 如何才能更快、更异步?我考虑在自己的 DataProvider 扩展 CallbackDataProvider 内部进行缓存,但它会在网格在第一次请求时收到空数据后填充,并且只能在再次刷新 DataProvider 一段时间后使用。这对我来说没有用。在我的实际项目中,获取的数据经常更改,并且项目数量较多,一个网格最多可达 100000 个项目,因此我需要使用请求大小有限的 CallbackDataProvider。

最佳答案

瓦丁 23:

在 Vaadin 23 中现在有一个新功能,它允许您为 DataCommunicator 定义执行器以用于与 Grid 进行异步操作。如果值为空,DataCommunicator 将同步运行,这是默认值。如果定义了执行程序,则执行程序将运行获取回调,并使用 UI#access(..) 更新网格。这需要启用推送。

grid.getDataCommunicator().enablePushUpdates(Executors.newCachedThreadPool());

瓦丁 14:

可以尝试使用缓存来减少查询时间。您可以使用一些通用缓存(例如 ehcache),也可以将缓存集成到数据提供程序中。它是特定于应用程序的,全局或本地缓存更适合您。

如果查询仍然需要那么长时间,那么我会为您的 UI 提出替代方法。不要使用回调数据提供程序,而是将 Grid 与内存数据提供程序一起使用,但不要立即将整个数据加载到数据提供程序。相反,创建一个分页 View 。当用户点击时查询新数据“下一个”/“上一个”等按钮。并在查询完成时使用 UI#access 异步方法更新 UI。

关于callback - Vaadin CallbackDataProvider 如何异步获取数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69942097/

相关文章:

java - 在 View 之间导航后,组件未正确加载

api - 用于 REST API 调用的 Yii2 数据提供者

javascript - 如何处理 Node 中的递归回调?

vaadin-flow - 不使用自定义主题时如何在 Vaadin 14.7.x 中启用徽章 CSS 类?

ios - 带有 tableView 按钮的交互式标题

在网格 ComponentRenderer 中使用时 ComboBox 的 Vaadin 12 ItemLabelGenerator

search - 在特定 Controller 方法中为 dataprovider 设置 where 条件

c# - .net mysql 连接器与 odbc mysql 连接器 3.51

javascript - 将回调添加到 JavaScript 函数中(AngularJS 上的应用)

reactjs - componentDidMount 和构造函数