Benedikt Schmidt
Benedikt Schmidt

Reputation: 2278

Vaadin Flow Access Current RouterLayout (from anywhere)

We have a RouterLayout class as a frame for the rest of our application, which includes different non-changing components, including a notification element, that needs to stay visible throughout navigation.

@CssImport("./styles/shared-styles.css")
public class MainFrame extends Composite<VerticalLayout> implements RouterLayout, PageConfigurator, AfterNavigationObserver {
    
    // central Notification that persists throughout navigation
    private Notification notification;


    // other stuff....

}

We're now trying to show this notification from anywhere within our code, so that all views, components and subcomponents are able to show a simple notification.

Unfortunately I'm not aware of an easy way to access the notification that exists inside the RouterLayout, because we can't access the layout level of the current UI. Putting the notification inside a view (router content) doesn't work, because it gets destroyed on navigation. Trying to use the event bus doesn't work, because event listeners inside the routerlayout won't be called when fired from inside the router content (as far as I've tested).

What we hope to achieve is to have a simple access class in a static fashion that is able to access the notification component of the currently set router.

public static void showNotification(String text) {
    // something like this
    MainFrame frame = ((MainFrame)UI.getCurrent().getRouterLayout()).showNotification(text);
}

Basicly we're unaware of an easy way to communicate with the currently set layout of the current UI from anywhere inside of our application, similar to UI.getCurrent(). Is there a way to achieve something like this?

Upvotes: 0

Views: 571

Answers (1)

Leif &#197;strand
Leif &#197;strand

Reputation: 8001

I wouldn't directly tie this to the concept of navigation and router layouts. What you have is functionality that is a "singleton" within the scope of a UI instance.

If using Spring or CDI, then this is natural to define as a managed bean in the UI scope that you can inject wherever needed.

Another alternative is to base the logic on UI.getCurrent(). The ComponentUtil method in Flow has setData and getData methods that you can use to attach your own custom instances to a specific component instance. You could thus do something like this:

ComponentUtil.getData(UI.getCurrent(), MainFrame.class).showNotification("Hello");

Upvotes: 3

Related Questions