如何将 MainView 注册到另一个 View 触发的 ComponentEvent?

How to register MainView to a ComponentEvent that another View fires?

如何将 MainView 注册到另一个 View 触发的事件?

我试过 ComponentUtil.addListener() 但它对我不起作用。另一方面,我什至不确定触发事件的视图是否在 MainView 可以注册到事件时创建?

申请流程:

打开应用程序 -> MainView -> 如果用户未通过身份验证则重新路由 -> LoginView -> SuccessfulAuthenticationEvent -> MainView 对 [=15= 做出反应] 在 LoginView

中被解雇

事件:

public class SuccessfulAuthenticationEvent extends ComponentEvent<LoginForm> {
    public SuccessfulAuthenticationEvent(LoginForm source, boolean fromClient) {
        super(source, fromClient);
    }
}

主视图:

public class MainView extends AppLayout implements ComponentEventListener<SuccessfulAuthenticationEvent> {
    ...
    @Override
    public void onComponentEvent(SuccessfulAuthenticationEvent event) {
        System.out.println("SuccessfulAuthenticationEvent catched");
    }
}

登录视图:

public class LoginView extends Div {
    ...
    @Override
    public void executeAfterAuthentication() {
        fireEvent(new SuccessfulAuthenticationEvent(loginForm, false));
    }
}

我会使用更稳健的不同方法。

在登录视图中。如果登录成功,则保存表示用户已登录的session属性,例如

VaadinSession.getCurrent().setAttribute("userLoggedIn", true);

在您的 MainLayout 中实现 BeforeEnterObserver 并覆盖 beforeEnter 方法。在beforeEnter方法中读取session属性,如果为空则转到登录页面。

@Override
public void beforeEnter(BeforeEnterEvent event) {
    if (VaadinSession.getCurrent().getAttribute("userLoggedIn") == null) {
        event.forwardTo(LoginView.class);
    }
}

额外小费。在 beforeEnter 方法中,您还可以存储当前路由,如果登录成功,则在登录视图中重新路由到存储的路由。

@Override
public void beforeEnter(BeforeEnterEvent event) {
    if (VaadinSession.getCurrent().getAttribute("userLoggedIn") == null) {
        VaadinSession.getCurrent().setAttribute("intendedPath", event.getLocation().getPath());
        ...
    }
}

并且登录成功后在登录视图

Object intendedPath = VaadinSession.getCurrent().getAttribute("intendedPath");
UI.getCurrent().navigate(Optional.ofNullable(intendedPath).map(Object::toString).orElse(""));