После фильтрации получите количество элементов, отображаемых в данный момент в виджете Grid в веб-приложении Vaadin 14. - PullRequest
0 голосов
/ 11 февраля 2020

В виджете Grid Vaadin 14, поддерживаемом ListDataProvider, после применения фильтра (ов) посредством вызова, такого как setFilter или addFilter

➥ Как определить , сколько элементов в поставщике данных отображается в данный момент пользователю?

Я заметил метод ListDataProvider::size. Но этот метод занимает Query с SerializablePredicate. Мои несколько фильтров уже были успешно применены, и мой Grid показывает подмножество элементов поставщика данных. Поэтому я не хочу запускать другой запрос. Я хочу узнать результаты применения фильтров уже .

Ответы [ 2 ]

1 голос
/ 11 февраля 2020

Пропуск new Query<>( myDataProvider.getFilter() ) в ListDataProvider::size

ListDataProvider имеет метод size(Query<T, SerializablePredicate<T>> query).

Поскольку поставщик данных хранит только исходный список элементов, простой метод size без параметров не будет работать так, как вы хотели. Вы можете создать требуемый запрос, используя текущие фильтры вашего поставщика данных.

Я протестировал следующий код, и он работает:

// my own method, defined as value change listeners of any filter field
private void onFilterChange(){
    ListDataProvider<Foo> dataProvider = (ListDataProvider<Foo>) grid.getDataProvider();
    dataProvider.setFilter((item) -> {......}

    // everytime after resetting the filter, check how many items now are displayed
    int filteredSize = dataProvider.size(new Query<>(dataProvider.getFilter()));

    int fullSize = dataProvider.getItems().size(); // this is how you get the size of all items
    Notification.show(String.format("Now showing %d of %d items", filteredSize, fullSize));
}

Возможно, в будущем эта работа может быть немного проще: См. Запрос-запрос Добавьте метод filteredSize к DataProvider или ListDataProvider # 7539 .

0 голосов
/ 11 февраля 2020

Вот подтверждение концепции с пользовательским ListDataProvider, который кэширует размер.

Во время вызова setFilter или во время вызова DataProviderListener счет не имеет еще был обновлен. Из-за этого мы используем UI.getCurrent().beforeClientResponse(...), чтобы отложить обновление текста.

public class MainView extends VerticalLayout {

    public MainView() {
        Grid<String> grid = new Grid<>();
        grid.addColumn(String::toString).setHeader("Value");

        MyDataProvider<String> myDataProvider = new MyDataProvider<>(
                Arrays.asList("One", "Two", "Three", "Four", "Five"));
        grid.setDataProvider(myDataProvider);

        Span countSpan = new Span();

        TextField filterField = new TextField("Filter");
        filterField.addValueChangeListener(e ->
                myDataProvider.setFilter(str -> str.contains(e.getValue())));

        // Use beforeClientResponse to give the grid time to filter the results
        myDataProvider.addDataProviderListener(e ->
                UI.getCurrent().beforeClientResponse(this, context ->
                        countSpan.setText(myDataProvider.getCachedSize() + " items in the grid")));

        add(filterField, grid, countSpan);
    }

    private static class MyDataProvider<T> extends ListDataProvider<T> {

        private int cachedSize;

        public MyDataProvider(Collection<T> items) {
            super(items);
        }

        @Override
        public int size(Query<T, SerializablePredicate<T>> query) {
            return (cachedSize = super.size(query));
        }

        public int getCachedSize() {
            return cachedSize;
        }
    }
}
...