You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vaadin 24 Grid基于最后记录Token的分页实现问询

Vaadin 24 Grid 滚动加载式游标分页实现

核心思路

基于Rest接口的Token驱动游标分页:首次请求获取100条记录并留存下一页Token,当用户滚动Grid接近底部时,携带Token调用接口获取新数据并追加到Grid中。

实现步骤

1. 定义数据结构

先创建适配接口返回的实体类和分页结果封装类:

// 业务实体类
public class Record {
    private String id;
    // 其他业务字段
    // Getter & Setter
}

// 接口返回的分页结果封装
public class PageResult<T> {
    private List<T> data; // 当前页数据列表
    private String nextToken; // 下一页请求的Token(无更多数据时为null)
    // Getter & Setter
}

2. 封装Rest接口调用逻辑

创建客户端类处理接口请求,支持携带Token参数:

@Component
public class DataApiClient {
    private final RestTemplate restTemplate;

    public DataApiClient(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public PageResult<Record> fetchRecords(String nextToken) {
        String url = "http://your-api-domain/records";
        if (nextToken != null) {
            url += "?nextToken=" + nextToken;
        }
        return restTemplate.getForObject(url, PageResult.class);
    }
}

3. Grid组件配置与滚动加载逻辑

在Vaadin视图中初始化Grid,实现首次加载和滚动触发的增量加载:

@Route("record-grid")
public class RecordGridView extends VerticalLayout {
    private final DataApiClient apiClient;
    private String nextToken;
    private boolean isLoading = false; // 防止重复请求的标记

    public RecordGridView(DataApiClient apiClient) {
        this.apiClient = apiClient;
        Grid<Record> grid = new Grid<>(Record.class);
        
        // 配置Grid列(按需调整)
        grid.addColumn(Record::getId).setHeader("记录ID");
        // 其他业务列配置...

        // 设置Grid占满容器
        grid.setSizeFull();
        add(grid);
        setSizeFull();

        // 加载初始数据
        loadInitialData(grid);

        // 监听Grid滚动事件,触发加载更多
        grid.addScrollListener(event -> {
            // 滚动到距离底部100px时触发加载
            boolean nearBottom = event.getScrollTop() + event.getClientHeight() >= event.getScrollHeight() - 100;
            if (nearBottom && !isLoading && nextToken != null) {
                loadMoreData(grid);
            }
        });
    }

    private void loadInitialData(Grid<Record> grid) {
        isLoading = true;
        PageResult<Record> initialResult = apiClient.fetchRecords(null);
        grid.setItems(initialResult.getData());
        nextToken = initialResult.getNextToken();
        isLoading = false;
    }

    private void loadMoreData(Grid<Record> grid) {
        isLoading = true;
        PageResult<Record> moreResult = apiClient.fetchRecords(nextToken);
        // 将新数据追加到Grid中
        grid.getLazyDataView().addItems(moreResult.getData());
        nextToken = moreResult.getNextToken();
        isLoading = false;
    }
}

关键注意事项

  • 防重复请求:通过isLoading标记避免滚动时多次触发接口调用
  • 滚动阈值:可调整event.getScrollHeight() - 100中的数值,提前触发加载提升用户体验
  • 错误处理:实际项目中需添加异常捕获(如接口请求失败),提示用户并重置isLoading状态
  • 后端配合:Rest接口需支持基于nextToken的游标分页,返回当前页数据和下一页Token(无数据时Token为null)

内容的提问来源于stack exchange,提问作者sethu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 15:17:36