в моем приложении Vaadin 14.2.0 есть BeforeLeaveListener для отображения диалогового окна подтверждения, когда ввод грязный (= есть несохраненные изменения в полях ввода), чтобы отменить (или намеренно продолжить) навигацию:
BeforeLeaveListener listener = new BeforeLeaveListener() {
@Override
public void beforeLeave(BeforeLeaveEvent event) {
if (dirtyFlag.isDirty()) {
ContinueNavigationAction postponeAction = event.postpone();
// show confirmation dialog and maybe execute a proceed
[...] () -> postponeAction.proceed();
}
}
};
UI.getCurrent().addBeforeLeaveListener(listener);
Это отлично работает для всего, кроме выхода из системы. Вот так моя кнопка выхода из системы выглядела в начале (что работает, пока я не хочу откладывать / отменять выход):
Anchor link = new Anchor();
link.getElement().addEventListener("click", e -> {
VaadinSession.getCurrent().getSession().invalidate();
UI.getCurrent().navigate(LoginView.class);
});
Теперь я хочу отложить выход из системы до тех пор, пока пользователь не подтвердит, что несохраненные изменения должны быть отменены. (Переключение обеих строк в EventListener кажется хорошей идеей, но не сработало из-за следующего.) Внутри вызова навигации вызывается BeforeLeaveListener (хорошо), но, тем не менее, выход из системы выполняется, потому что код после перехода () -call выполняется (конечно, потому что это не блокирующий вызов), сеанс аннулируется, и пользователь выходит из системы, хотя диалоговое окно подтверждения только что появилось (но у пользователя не было возможности подтвердить / отклонить).
Я попытался переместить аннулирование сеанса в LoginView (в BeforeEnterObserver), но в результате представление входа в систему перезагружалось в бесконечном цикле.
Вопрос: есть ли что-то вроде «перейдите в LoginView, и если навигация не откладывается и не отменяется, то аннулировать сеанс»?
Обходной путь - перейти к перехватывающему Log out View, который просто аннулирует сеанс и перенаправляет / пересылает на LoginView:
@Route(value = "logout")
public class LogoutView implements BeforeEnterObserver {
@Override
public void beforeEnter(BeforeEnterEvent event) {
VaadinSession.getCurrent().getSession().invalidate();
event.forwardTo(LoginView.class);
}
}
Но мне кажется, что это просто плохой обходной путь с некоторыми накладными расходами (создание представления только для перехода к другому представлению) ...