Как определить, был ли обновлен компонент пользовательского интерфейса в Vaadin 8

В приложении на основе Vaadin 8 я хочу реализовать команду, которая удаляет значение всех полей. Я сделал это с помощью Binder. Когда пользователь активирует команду, будет создан новый Bean.

    @Override public void menuSelected(MenuBar.MenuItem selectedItem) {

    controller.createNewBean();
    Page.getCurrent().reload();

}

Я хочу показать пользователю окно сообщения, которое предупреждает, что при продолжении все значения для всех компонентов будут потеряны. Я использую TabView, и компонентов относительно много.
Я хочу показывать это сообщение, только если пользователь изменил значение хотя бы для одного компонента. Интересно, есть ли у Vaadin что-то вроде UI.getCurrent().isDirty() или другого механизма для определения того, ввел ли пользователь новое значение для компонента?

Спасибо за помощь


person Govan    schedule 13.06.2017    source источник


Ответы (2)


Самый эффективный способ, который я нашел, заключался в регистрации нового слушателя в связующем, чтобы получать уведомления о любых изменениях в значении компонента.

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

Не то чтобы это не обнаруживает изменений, но обнаруживает модификации (например, пользователь может изменить значение поля несколько раз, но в конце концов установить исходное значение).

AtomicInteger counter = new AtomicInteger();
binder.addValueChangeListener((HasValue.ValueChangeListener<Object>) event -> counter.incrementAndGet());

Обязательно сбрасывайте счетчик при необходимости (например, во время сохранения).

person Youness    schedule 22.03.2019
comment
Элегантное решение! В Vaadin 14.1.23 часть дженериков немного отличается (по крайней мере, от того, что принимает мой Eclipse): binder.addValueChangeListener((HasValue.ValueChangeListener‹? super ValueChangeEvent‹?››) event -› counter.incrementAndGet()); - person S. Doe; 05.04.2020

Вы можете использовать binder.hasChanges(). Это в основном проверяет, различаются ли ваши поля и базовый компонент, привязанный к полям, из-за взаимодействия с пользователем.

Из документов Ваадина:

Проверьте, не изменились ли какие-либо значения связанных полей с момента последнего явного вызова setBean(Object), readBean(Object), removeBean(), writeBean(Object) или writeBeanIfValid(Object).

См. API Vaadin и Vaadin Doc. главу Привязка данных к формам для получения дополнительной информации.

С Page.getCurrent().reload() вы получаете новый пользовательский интерфейс, и все ваши компоненты сбрасываются, как если бы вы открыли новую вкладку. Для сброса ваших компонентов я бы рекомендовал использовать binder.readBean(theNewBeanWithFreshValues). Это устанавливает значения связанных полей обратно в значения bean-компонента.

person Axel Meier    schedule 13.06.2017
comment
Спасибо @ Аксель Мейер. Кажется, единственный способ — это binder.hasChanges(). Проблема в том, что у меня есть разные Bean-компоненты и разные вкладки, и я должен знать о многих связующих элементах. Из-за этого я также использую перезагрузку вместо readBean. - person Govan; 14.06.2017
comment
Я протестировал реализацию с помощью связывателя hasChanges. Он не работает, как описано в документации. См. это: vaadin.com/forum/#!/thread/14906891/15007809 - person Govan; 14.06.2017
comment
@Govan Спасибо за ваш отзыв. Действительно, hasChanges() имеет смысл использовать в сочетании с readBean() и writeBean(). С setBean() изменения автоматически фиксируются, hasChanges() возвращает false. Также с setBean() больше нет возможности восстановить старые значения. - person Axel Meier; 14.06.2017