Калитка: Как я могу скрыть столбец в таблице данных, если каждая ячейка пуста или содержит скрытый компонент?

#wicket

#калитка

Вопрос:

У меня есть столбец в моей таблице, где я заполняю элемент следующим кодом:

     @Override
    public void populateItem(Item<ICellPopulator<T>> item, String componentId, IModel<T> model) {
        if (deleteEnabled(model)) {
            item.add(new ConfirmationLink<>(componentId).onClick(target -> deleteRow(...)));
        } else {
            item.add(new Label(componentId));
        }
    }
 

Поэтому, когда у пользователя достаточно разрешений для удаления объекта, он может видеть значок в строке, если нет, он видит только пустую ячейку.

Где я могу проверить для каждой модели в таблице, что у пользователя нет разрешения на удаление любого объекта и предотвращение отображения столбца в таблице?

Обновить

Я хотел бы добавить некоторый код, чтобы объяснить мой случай.

Это очень распространенный пример использования таблицы в моем приложении.

 public class CenterPanel extends SWPanel<CourierSearchQuery> {

    public CenterPanel(String id) {
        super(id, new Model<>(new CourierSearchQuery()));
    }

    @Override
    protected void onInitialize() {
        super.onInitialize();
 
        List<IColumn<Courier, String>> columns = List.of(

                new StyledColumn<Courier>("Ф.И.О.", "name.FIO", "name.FIO")
                        .setCreateComponentFunction((id, model) ->
                                new LinkPanel(id, model.map(n -> n.getName().getFIO()), model)),

                new StyledColumn<Courier>("Статус", "state.title")
                        .setCssClass(CSS.width(100)),

                new StyledColumn<Courier>("Телефон", "phone")
                        .setCssClass(CSS.width(100)),

                new DeleteColumn<>() // <- this column should be hideable
        );

        add(new EntityDataTable<>("table", columns, getModel()));
    }
}
 

Существует объект JPA (Courier), объект параметров POJO (CourierSearchQuery), где я могу установить критерии для фильтрации данных и EntityDataTable. Последний содержит dataprovider, который может найти DAO для объекта, вызвать метод поиска с параметрами фильтра и создать итератор над ним.

Также существует класс DeleteColumn . Под капотом он проверяет разрешения пользователя для текущего объекта и показывает ссылку ajax.

Я хотел бы пометить его следующим интерфейсом и скрыть его внутри класса DataTable (при необходимости):

 public interface HideableColumn<T> {

    boolean isCellVisible(T object);
}
 

Для реализации скрытия я написал следующее:

 
    private List<? extends IColumn<T, String>> allColumns;

    @Override
    protected void onConfigure() {
        super.onConfigure();

        if (allColumns == null) allColumns = new ArrayList<>(getColumns());

        if (allColumns.stream().anyMatch(e -> e instanceof HideableColumn)) {
            getColumns().clear();

            Set<T> objects = new HashSet<>();
            getDataProvider().iterator(getCurrentPage() * getItemsPerPage(), getItemsPerPage()).forEachRemaining(objects::add); // <-1

            allColumns.stream()
                    .filter(e -> !(e instanceof HideableColumn) || objects.stream().anyMatch(((HideableColumn<T>) e)::isCellVisible))
                    .forEach(e -> getColumns().add(e)); // <-2
        }
    }
 

Но у этого кода есть две проблемы:
1 — это заставляет таблицу дважды вызывать dataProvider#iterator()
2 — он не компилируется из-за того, что DataTable#getColumns() имеет подстановочный знак в объявлении

Ответ №1:

Итак, если все строки в столбце пусты, вы вообще не отображаете столбец?

В этом случае я предлагаю два варианта:

  1. В калитке: сначала проверьте разрешения и не добавляйте столбец в первую очередь
  2. В JavaScript: проверьте, пуст ли столбец, и скройте его, вероятно, есть решения для этого в Интернете.

Ответ №2:

Переопределите функцию #onconfigureвашей таблице(), выполните итерацию по всем элементам данных и удалите / добавьте столбец соответствующим образом.

Комментарии:

1. Как я могу получить текущие значения предела и смещения в методе DataTable#onConfigure()?

2. Вы можете использовать DataTable#getItemsPerPage() и #getCurrentPage() .

3. Хорошо, это было бы рабочим решением, но коллекция ‘columns’ в таблице данных объявлена как список с расширенными границами, поэтому в нее невозможно добавить какой-либо элемент. Кроме того, он является окончательным, и я не могу просто установить другую коллекцию вместо существующей.

4. Вы правы. Но ваш код в подклассе или содержащем родительском элементе сохраняет список столбцов без подстановочных знаков по мере необходимости.

5. Это так, но оно не содержит модели данных и строк. Данные загружаются dataProvider, а загрузка данных инициируется таблицей после определения списка столбцов.