首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Vaadin23 ComBox自动完成并“试图一次从服务器获取比允许的更多的项”

Vaadin23 ComBox自动完成并“试图一次从服务器获取比允许的更多的项”
EN

Stack Overflow用户
提问于 2022-07-28 14:57:39
回答 1查看 86关注 0票数 0

我正在尝试用自动完成功能实现我的第一个Vaadin ComboBox。到目前为止,这就是我所拥有的:

代码语言:javascript
复制
    ComboBox<CompositeEntityResult> companyComboBox = new ComboBox<>("Company");
    companyComboBox.setRequired(true);
    companyComboBox.setItems(new CompanyBackEndDataProvider(companyService));
    companyComboBox.setPageSize(20);
    companyComboBox.setAllowCustomValue(true);
    companyComboBox.setItemLabelGenerator(e -> TranslationUtils.getTranslatedName(e.getNode()));

如您所见,我添加了CompanyBackEndDataProvider,如下所示:

代码语言:javascript
复制
public class CompanyBackEndDataProvider extends AbstractBackEndDataProvider<CompositeEntityResult, String> {

    private final CompanyService companyService;

    public CompanyBackEndDataProvider(CompanyService companyService) {
        this.companyService = companyService;
    }

    @Override
    protected Stream<CompositeEntityResult> fetchFromBackEnd(Query<CompositeEntityResult, String> query) {
        Stream<CompositeEntityResult> stream = Stream.empty();
        Optional filter = query.getFilter();
        if (filter.isPresent()) {
            int page = query.getPage();
            int pageSize = query.getPageSize();
            String namePattern = (String) filter.get();
            if (StringUtils.isNoneBlank(namePattern)) {
                List<CompositeEntityResult> compositeEntityResults = companyService.findByNamePattern(namePattern, VaadinUtils.getCurrentLocaleIso6391(), page, pageSize);
                stream = compositeEntityResults.stream();
            }
        }
        return stream;
    }

    @Override
    protected int sizeInBackEnd(Query<CompositeEntityResult, String> query) {
        int size = 0;
        Optional filter = query.getFilter();
        if (filter.isPresent()) {
            String namePattern = (String) filter.get();
            if (StringUtils.isNoneBlank(namePattern)) {
                size = (int) companyService.findByNamePatternCount(namePattern);
            }
        }
        return size;
    }

}

乍一看,一切正常,但当返回的查询项中有很多项时,当我向下滚动项目时,会在控制台中看到以下消息:

代码语言:javascript
复制
WARN 2992 --- [nio-8080-exec-7] c.v.flow.data.provider.DataCommunicator  : Attempted to fetch more items from server than allowed in one go: number of items requested '220', maximum items allowed '200'.

此外,我可能会看到在ComboBox弹出窗口中保留了大量空空间,其中有一个滚动条:

我做错了什么,怎么解决呢?

更新

当我将代码更改为简单的时候,我可能会看到同样的问题:

代码语言:javascript
复制
companyComboBox.setItems(query ->
        companyService.findByNamePattern(query.getFilter().get(), VaadinUtils.getCurrentLocaleIso6391(), query.getOffset(), query.getLimit()).stream()
);

另外,当我删除以下行时:

代码语言:javascript
复制
companyComboBox.setPageSize(20);

一切都好起来了..。奇怪..。仍然不理解companyComboBox.setPageSize(20);与上述问题之间的相关性

EN

回答 1

Stack Overflow用户

发布于 2022-08-05 11:08:13

听起来像是虫子。如果你检查https://vaadin.com/api/platform/23.1.4/com/vaadin/flow/component/combobox/ComboBox.html

ComboBox支持延迟加载。这意味着当使用大数据集时,当用户向下滚动覆盖时,从服务器请求一个“页面”项。默认情况下,一页中的项目数为50,可以使用setPageSize(int)进行更改。

但这不是真的,可以用

代码语言:javascript
复制
        ComboBox<Integer> comboBox = new ComboBox<>();;
        comboBox.setItems((item, filterText) -> true, IntStream.range(0, 250).boxed().collect(Collectors.toList()));
        comboBox.setPageSize(20);

另一方面,setPageSize()的javadoc:

--这并不保证向后端提供最大的查询大小;当覆盖层有空间呈现比页面大小更多的新项时,将同时请求多个“页面”。

https://vaadin.com/api/platform/23.1.4/com/vaadin/flow/component/combobox/ComboBox.html#setPageSize(int)。但似乎与之前的相悖?

在不更改页面大小的情况下这样做的原因:

代码语言:javascript
复制
public class DataCommunicator<T> implements Serializable {

    private static final int MAXIMUM_ALLOWED_PAGES = 10;

    ...

    private int getMaximumAllowedItems() {
        return MAXIMUM_ALLOWED_PAGES * pageSize;
    }
...

因此,通过更改pageSize (默认值为50),我们也更改了限制(这是我所不期望的,或者至少是预期会被记录在案)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73154918

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档