当前位置: 首页 > 知识库问答 >
问题:

Vaadin DataProvider:如何避免“自动获取”?

慕凌
2023-03-14

至少有两个用例:

  • 除非用户提供筛选器参数,否则显示网格数据是没有意义的
  • 返回@preserveonrefresh标记视图时,不应将显示的数据替换为当前数据。(更新中有进一步阐述)

作为Vaadin 14+的新手,我不知道如何实现这一点。每次显示我的GridView时,都会查询DataProvider的count和fetch回调。调用来自网格的DataCommunicator

        at org.vaadin.example.GridView.fetch(GridView.java:46)
        at org.vaadin.example.GridView.lambda$new$c4b2c115$1(GridView.java:23)
        at com.vaadin.flow.data.provider.CallbackDataProvider.fetchFromBackEnd(CallbackDataProvider.java:137)
        at com.vaadin.flow.data.provider.AbstractBackEndDataProvider.fetch(AbstractBackEndDataProvider.java:61)
        at com.vaadin.flow.data.provider.DataCommunicator.fetchFromProvider(DataCommunicator.java:362)
        at com.vaadin.flow.data.provider.DataCommunicator.activate(DataCommunicator.java:647)
        at com.vaadin.flow.data.provider.DataCommunicator.collectKeysToFlush(DataCommunicator.java:589)
        at com.vaadin.flow.data.provider.DataCommunicator.flush(DataCommunicator.java:461)
        at com.vaadin.flow.data.provider.DataCommunicator.lambda$requestFlush$2f364bb9$1(DataCommunicator.java:425)
        at com.vaadin.flow.internal.StateTree.lambda$runExecutionsBeforeClientResponse$2(StateTree.java:390)
        at [java.util.stream] omitted
        at com.vaadin.flow.internal.StateTree.runExecutionsBeforeClientResponse(StateTree.java:387)
        at com.vaadin.flow.server.communication.UidlWriter.encodeChanges(UidlWriter.java:411)
        at com.vaadin.flow.server.communication.UidlWriter.createUidl(UidlWriter.java:187)
        at com.vaadin.flow.server.communication.UidlRequestHandler.writeUidl(UidlRequestHandler.java:122)
        at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:91)
        at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
        at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1547)
        at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:247)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
@Route(value = "grid", layout = MainView.class)
public class GridView extends VerticalLayout {
    public GridView() {
        final Grid<Person> g = new Grid(Person.class);
        g.setColumns("name");
        g.setDataProvider(DataProvider.fromCallbacks(q -> fetch(q), q -> count(q)));
        add(g);
        // filter omitted
        final Button refresh = new Button("refresh");
        refresh.addClickListener(e -> {
            System.out.println("refresh clicked");
            g.getDataProvider().refreshAll();
        });
        add(refresh);

        add(new TextField("State check"));
    }

    // fake DataProvider
    private int count(Query<Person, Void> q) { return 3; }

    private Stream<Person> fetch(Query<Person, Void> q) {
        q.getLimit(); //vaadin checks these have been called
        q.getOffset(); //vaadin checks these have been called
        System.out.println("fetching again");
        new Exception().printStackTrace(); //figure out who called
        return Arrays.asList(new Person("1"), new Person("2"), new Person("3")).stream();
    }
}

我的MainView用于在GridViewEmptyView之间切换

@PreserveOnRefresh
public class MainView extends AppLayout {

    private Component emptyBView;
    private Component gridBView;

    public MainView() {
        final Button emptyB = new Button("Btn empty");
        emptyB.addClickListener(e -> {
            if (emptyBView == null) { emptyBView = new EmptyView();}
            setContent(emptyBView);
        });
        addToNavbar(emptyB);

        final Button gridB = new Button("Btn grid");
        gridB.addClickListener(e -> {
            if (gridBView == null) gridBView = new GridView();
            setContent(gridBView);
        });
        addToNavbar(gridB);
    }
}

MainView是一个applayout,用于将applayout的内容从gridview切换到emptyview

用例2是:当返回到GridView时,GridView的状态应该与以前完全相同(这与TextField很好地配合)。

  1. 打开gridview->网格不应填充数据
  2. 输入筛选器参数(代码中未显示)
  3. 单击“刷新”填充网格
  4. textfield“statecheck”
  5. 中输入“蜘蛛侠”
  6. 切换到emptyview
  7. 在实际应用程序中:在emptyview和其他视图中执行某些操作
  8. 返回gridview->网格不应该重新加载数据,它应该保持原样-就像textfield仍然显示“蜘蛛侠”一样,网格应该显示与以前相同的数据而不重新加载它。

共有1个答案

齐建安
2023-03-14

对于情况1:在回调检查中,如果有筛选器参数,则返回一个空集。使用新的V17+API,其外观如下所示:


grid.setItems(query -> {
    if(filterParameters.isEmpty()) {
      // Return an empty stream
    } else {
      // Fetch from backend
    }
});

您可以在以下文档中阅读更多内容:https://vaadin.com/docs/latest/flow/binding-data/data-provider(V19)或https://vaadin.com/docs/V14/flow/binding-data/tutorial-flow-data-provider(V14)

我需要更多关于你目前正在做什么的信息来帮助解决案例2。您是如何构造视图的,您的代码是什么样子的?带有“原因”的完整堆栈跟踪也会有所帮助。

 类似资料:
  • 问题内容: 我正在尝试通过从客户端向服务器发送密钥和随机数来认证用户。 我的代码未向我显示客户端的响应。执行下面的代码时,我得到了一个空指针异常。 问题答案: 解决大多数问题的固定步骤: 阅读堆栈跟踪以确定哪一行代码引发NPE 在该行代码处设置一个断点 使用调试器,在遇到断点时,确定该行中的对象引用是 弄清楚为什么引用该文件(到目前为止,这是唯一实际的困难部分) 解决根本原因(也可能很困难)

  • 问题内容: 我有两个简单的Java代码。第一个将恒定功率定义为power = a.pow(b); 第二个将恒定功率定义为power = BigInteger.ONE.shiftLeft(b) 在命令行中设置内存标志- Xmx1024m,第一个代码可以正常工作,但是第二个代码却出现错误:java.lang.OutOfMemoryError:Java堆空间 我的问题:我应该在第二个代码中更改什么以避免

  • 问题内容: 我有一个用于将文本添加到现有.doc文件中的代码,它将通过使用apache POI将其另存为另一个名称。 以下是到目前为止我尝试过的代码 以下是我得到的 我已经添加了与此对应的所有jar文件,但仍然找不到解决方案。我对apache poi是陌生的,所以请帮我提供一些解释和示例。谢谢 问题答案: 从我对问题的评论中复制: 看起来您需要Apache POI发行版中的poi-ooxml-sc

  • 我有一个NetBeans项目,我想在其中设计jasper报表,当我通过填充报表时,我发现了一条错误消息。 例外情况是: 线程“awt-eventqueue-0”java.lang.noClassDefounderror:org/apache/commons/logging/logFactory在net.sf.jasperReports.engine.util.jrloader.(jrloader.

  • 频繁启动<code>Eclipse Juno<code>时,我发现<code>服务器无法启动</code>我删除了<code>。快照和临时文件夹,但我经常遇到同样的问题。 如果我更改工作空间,有时它会运行,有时它不会启动。为什么会这样?如何避免? 请清除我的问题,我经常得到它。

  • 我想问你,是否有一种方法可以避免Azure中的应用程序服务计划自动缩小。例如,我使用以下定价层配置了一个应用程序服务计划:基本:1中等;然而,如果我的应用程序空闲一段时间,该应用程序服务计划的定价层将更改为共享。我不知道这是否是一种标准行为,从经济上讲是有道理的;然而,从技术角度来看,我确实需要至少一个基本的服务计划,因为我正在使用一些共享环境中不可用的GDI功能(实际上我的应用程序开始崩溃)。