Как вы связываете видимость компонента с состоянием модели - PullRequest
1 голос
/ 02 марта 2020

Допустим, у меня есть Grid, содержащий некоторые Item с и specialActionButton, которые я хочу отображать, только когда элемент, выбранный в grid, имеет тип special.

или Я хочу отключить кнопку, пока не будет выполнено какое-либо условие для модели.

В настоящее время я думаю о невидимом поле, связанном с фальшивкой Validator, которая обновляет пользовательский интерфейс.

Но это кажется таким плохим способом go об этом, что я почти уверен, что должен быть лучший способ.

Ответы [ 3 ]

2 голосов
/ 02 марта 2020

Ситуация 1: кнопка находится за пределами сетки
Вы можете определить SelectionListener в сетке, где вы можете проверить свои критерии для выбранного элемента. В зависимости от этого результата вы вызываете button.setVisible(itemFulfillsCriteria);

// assuming a single select grid
grid.addSelectionListener(selection -> {
    boolean showButton = false;
    MyItem selectedItem = selection.getFirstSelectedItem().orElse(null);
    if(selectedItem != null && selectedItem.getFoo() == Foo.BAR){ // show button only if item.foo == BAR
        showButton = true;
    }
    myButton.setVisible(showButton);
    //myButton.setEnabled(showButton); // if you want to disable instead of hide.
}

Ситуация 2: кнопка для каждой строки сетки
Когда вы добавляете столбец для этой кнопки, вы можете проверить внутри Рендерер, если элемент соответствует наличию этой кнопки видимой.

grid.addComponentColumn(item -> {
    if(item.getFoo() == Foo.BAR) {
        return new Button("click me", click -> {
            // do something when clicked
        });
    } else {
        return new Span(); // don't return null, as that would cause exception. Instead, return empty Span.
    }
})
    .setKey("someAction")
    .setHeader("Do the thing");

Ситуация 3: нет сетки, но есть Binder Когда у вас есть переплет и вы хотите показать / скрыть или включить / Отключить компонент, основываясь на значениях связанных элементов, вы можете определить ValueChangeListener для самого подшивки. В любое время, когда значение связанного входного поля изменяется, этот слушатель будет срабатывать, и тогда вы сможете проверить, соответствует ли связанный элемент вашему критерию, и действовать соответствующим образом.

binder.addValueChangeListener(changeEvent -> {
    MyItem boundItem = binder.getBean();
    button.setVisible(boundItem.getFoo() == Foo.BAR);
    //button.setEnabled(boundItem.getFoo() == Foo.BAR);
}
2 голосов
/ 02 марта 2020

Если вы хотите, например, чтобы отключенное состояние кнопки контролировалось логическим свойством в вашей модели, оно должно каким-то образом уведомляться об изменении логического значения.

Для общего подхода c вы можете интересоваться Просмотр моделей для Java компонентов . Обратите внимание, что подход в статье является экспериментальным и не является частью официального предложения Ваадина.

2 голосов
/ 02 марта 2020

Вы должны быть в состоянии добиться поведения, используя ComponentRender. Взгляните на пример здесь: Использование компонентных средств визуализации . Вместо Icon вы можете вернуть либо отключенную / активированную кнопку.

Например, что-то вроде этого:

grid.addColumn(new ComponentRenderer<>(property -> {
        NativeButton button=new NativeButton("Remove");
        if (property.getValue().contains("1")) {
            return button;
        } else {
            button.setEnabled(false);
            return button;
        }
})).setHeader("button");

После обновления элемента и вызова dataProvider.refreshItem(item); свойство enabled изменится

Другим подходом будет использование setClassNameGenerator. К сожалению, в документации нет примера, но (кроме способа импорта стилей) эта тема очень актуальна: Как установить цвет ячейки в Grid в Vaadin 13?

...