vaadin - 由数据提供者填充的网格 : how to trigger an action after refreshment?

标签 vaadin vaadin8 vaadin-grid

在 Vaadin 8.2 中,我有一个使用数据提供程序 (AbstractBackEndDataProvider) 绑定(bind)到 bean 的网格。从数据库中获取数据,应用过滤器:

Grid grid = new Grid<>();
grid.setDataProvider(dataProvider.withConfigurableFilter()); // dataProvider derives from AbstractBackEndDataProvider<T,F>

基本流程如下:用户在表单中输入项目 ID 并提交,提交事件监听器获取用户输入,创建新过滤器并更新数据提供者:

filterSubmitButton.addClickListener(event -> {
    try {
        ItemListFilter filter = new ItemListFilter(
            itemFilter.getValue(), // itemFilter = new TextField();
        );
        filterBinder.writeBean(filter);
        dataProvider.setFilter(filter);
    } catch (ValidationException e) {
        //...
    }
 });

当数据提供者更新过滤器时,它会调用一个服务来从数据库中获取新项目并应用过滤器(对数据库查询)。 Vaadin 负责随后使用新数据刷新网格。

我想要的是在这最后一刻有一个回调。假设一个用例是检查过滤的提取结果集是否仅包含一个项目,以在网格中选择该项目(这将触发一个事件,在另一个 Pane 中显示项目详细信息)。或者在加载初始列表后选择第一个网格行

但问题是既没有grid.addRefreshListener()也没有dataProvider.addRefreshmentListener()。任何其他听众似乎都不适用于这种情况。

提前感谢您的帮助。

最佳答案

我找到的唯一解决方案是权衡取舍。

项目列表展示器(用网格处理 View )将其 com.vaadin.event.EventRouter 传递给 dataProvider(我修改了 dataProvider 持有一个 EventRounter 作为成员)。现在,我不再直接从 dataProvider 流式传输 DB 结果,而是触发一个事件以获取数据(使用 EventRouter)。展示者可以订阅这个事件,然后委托(delegate)给详情面板的展示者。在那里你可以读取获取的结果(事件包含它们),检查是否只有一个条目并通过 id 打开它。

public class ListItemDataProvider extends AbstractBackEndDataProvider<Item, ItemFilter> {
    //...
    @Override
    protected Stream<Item> fetchFromBackEnd(Query<Item, ItemFilter> query) {
        // ...
        List<Item> fetchedResults = service.fetch(query.getOffset(), query.getLimit(), orderBy, getFilter(query));
        eventRouter.fireEvent(new FilteredDataFetchedEvent(this, fetchedResults));
        return fetchedResults.stream();
    }
}


@Controller
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ItemListPresenter {
    // ...
    public void addFilteredDataFetchedListener(ItemListView.FilteredDataFetchedListener listener) {
        eventRouter.addListener(FilteredDataFetchedEvent.class, listener, FilteredDataFetchedListener.FILTERED_DATA_FETCHED);
    }
}

一些注意事项:

  1. 这不是我需要的。是的,我可以做我的大部分用例,如果应用过滤器,列表会重新加载,详细信息 View 也会让事件重新加载。但是我不能为此重新使用“selectionChanged”事件监听器,实际上根本无法在网格中选择一行(只是因为 dataProdiver 中的事件在网格更新之前被抛出).
  2. 这是一个肮脏的把戏,因为现在 dataProvider 抛出事件并处理 View /演示者的 eventRouters。另一方面,Vaadins 数据提供者无论如何都允许订阅事件。使用开箱即用的 grid-dataProvider 响应式(Reactive)绑定(bind),我们只是在获取数据后没有触发事件,所以我们以自定义方式进行。
  3. 还可以使用给定的 Vaadin 订阅者 dataProvider.addDataProviderListener 并从那里委托(delegate)一个包含已填充过滤器的事件,然后在详细信息面板中独立捕获该事件。但是你需要执行两次 sql 查询(这可能是昂贵的)或缓存它们等。与给定的相比,这没有带来任何好处,仍然是一种权衡。

关于vaadin - 由数据提供者填充的网格 : how to trigger an action after refreshment?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48209978/

相关文章:

java - Vaadin Textarea 自动高度

java - 有没有办法在可编辑的 Vaadin 8 网格中设置验证并编辑长值

vaadin - 如何滚动到 Vaadin 网格中当前选定的行?

vaadin - Vaadin 13 Grid 中是否有一个 "Select All"checkbok(即使有过滤条件也能工作,甚至有些数据不在缓存中?)

vaadin - 如何向 Vaadin 表显示 java.util.Properties 对象列表?哪个容器可以直接提供帮助而不需要循环?

java - 如何使用Vaadin的CustomLayout自定义样式?

drop-down-menu - Vaadin 8 NativeSelect更改列表的数据表示形式

vaadin - 编辑网格时是否可以在 GridPro 上的 Vaadin 14 中显示保存/取消按钮

vaadin - 新的 Vaadin 应用程序在运行时显示我的应用程序正在使用属于 Vaadin 订阅一部分的组件

java - 如何在 Vaadin 中编辑不可变对象(immutable对象)列表?