Navigator in Flow with MPR
This step is needed in case your Vaadin 7 or 8 application uses Navigator. If it isn’t the case, go back to the framework selection.
The navigation with MPR can be done in three ways. You can choose the one most suitable for your application, but don’t mix them together. No other approach is supported at the moment.
The first way is to use the Navigator together Flow’s Router. This is suitable for creating new views in Flow while maintaining the old views to be routed by the Navigator
.
The second is using the Navigator without mixing with Flow. It’s suitable for projects with complex custom navigators.
Last, using only the Flow’s Router is suitable for basic navigation setups that can be easily ported, or as the final stage of an incremental porting process.
Note
|
Keep in mind that the old Navigator uses URLs with the "hash-bang" (#! ) prefix. That prefix isn’t used by the Flow’s Router.
|
Mixing Navigation & Flow Routing
It’s possible to use the legacy Navigator and Flow routing together.
Starting from the legacy application:
public class NavigatorUI extends UI {
@Override
protected void init(VaadinRequest request) {
CssLayout viewDisplay = new CssLayout();
Navigator navigator = new Navigator(this, viewDisplay);
navigator.addView("", HomeView.class);
navigator.addView("away", AwayView.class);
VerticalLayout content = new VerticalLayout(viewDisplay);
setContent(content);
}
}
You would make the UI
into a Flow route by extending MprNavigatorRoute
.
@Route("")
public class MyNavigatorRoute extends MprNavigatorRoute {
@Override
public void configureNavigator(Navigator navigator) {
navigator.addView("", HomeView.class);
navigator.addView("away", AwayView.class);
}
}
For a more complex example, you could have a MainMenu
component that’s always visible and used to navigate between the views:
public class MyNavigatorUI extends UI {
@Override
protected void init(VaadinRequest request) {
CssLayout viewDisplay = new CssLayout();
Navigator navigator = new Navigator(this, viewDisplay);
navigator.addView("", HomeView.class);
navigator.addView("away", AwayView.class);
setContent(new VerticalLayout(new MainMenu(), viewDisplay));
}
}
public class MainMenu extends HorizontalLayout {
public MainMenu() {
Button home = new Button("Home",
event -> getUI().getNavigator().navigateTo(""));
Button away = new Button("Away",
event -> getUI().getNavigator().navigateTo("away"));
addComponents(home, away);
}
}
Here we can move the MainMenu
to its own RouterLayout
that’s used on all
Routes that have it as the parent layout. All you need to do is create a Flow
component (e.g., MainLayout
) that contains the MainMenu
component and add
that to the @Route
annotation.
// Flow router target
@Route(value = "", layout = MainLayout.class)
public class MyNavigatorRoute extends MprNavigatorRoute {
@Override
public void configureNavigator(Navigator navigator) {
navigator.addView("", HomeView.class);
navigator.addView("away", AwayView.class);
}
}
// Flow layout, used by the router
public class MainLayout extends VerticalLayout implements RouterLayout {
public MainLayout() {
add(new LegacyWrapper(new MainMenu()));
}
}
This way you can make a single MainLayout
that can be used both with the old navigator views, as well as with the new Flow views.
To add a Flow view we need to create the route target:
@Route(value = "flow", layout = MainLayout.class)
public class FlowView extends Div {
}
Then add it to the MainMenu
as a Button
:
public class MainMenu extends HorizontalLayout {
public MainMenu() {
Button home = new Button("Home",
event -> getUI().getNavigator().navigateTo(""));
Button away = new Button("Away",
event -> getUI().getNavigator().navigateTo("away"));
Button flow = new Button("Flow",
event -> getUI().getNavigator().navigateTo("flow"));
addComponents(home, away, flow);
}
}
Now the menu can be used to navigate from a legacy view to a Flow view and back.
When requesting the Navigator
to navigate to a view that isn’t registered in the Navigator
, navigate to a corresponding Flow view, if available. Navigation from a Flow route to a legacy View also works through the Navigator
.
By default the MprNavigatorRoute
creates a <div>
on the client-side, but this can be changed by annotating the subclass with @Tag
.
MainMenu
, HomeView
and AwayView
are legacy Vaadin 7 components and, FlowView
and MainLayout
are Flow components. HomeView
and AwayView
also implement View
.
Use Navigator Without Flow Mixing
Navigator can be used as is by having a view display component that is
wrapped in a LegacyWrapper
.
Consider the following simple legacy navigator setup:
public class MyUI extends UI {
@Override
protected void init(VaadinRequest request) {
Navigator navigator = new Navigator(this, this);
navigator.addView("", DefaultView.class);
navigator.addView("subview", SubView.class);
}
}
This would be changed to the following:
@Route("")
public class Root extends Div {
private final CssLayout content = new CssLayout();
public Root() {
add(new LegacyWrapper(content));
Navigator navigator = new Navigator(UI.getCurrent(), content);
navigator.addView("", DefaultView.class);
navigator.addView("subview", SubView.class);
}
}
Now, navigation to localhost
would show DefaultView
and localhost#!subview
would show SubView
, as is expected. The thing to note in this case is that Flow doesn’t receive any view change events.
Upgrading Views to Flow Routes
Another open path for navigator upgrade is to wrap the existing View
classes into a MprRouteAdapter<? extends View>
and give the adapter class a Route
. Then the navigator.addView("away", AwayView.class);
configuration in the previous example would be changed to:
@Route(value = "away", layout = MainLayout.class)
public class AwayRoute extends MprRouteAdapter<AwayView> {
}
By default the MprRouteAdapter
creates a <div>
on the client-side, but this can be changed by annotating the subclass with @Tag
.
Now, there is no need to setup a Navigator
and the View still receives a ViewChangeEvent
as it did with the navigator.
Any ViewChangeListener
should be replaced with a BeforeEnterListener
for the beforeViewChange
and an AfterNavigationListener
for the afterViewChange
to the Flow UI. See Navigation Lifecycle documentation.
The next step is Configuring UI Parameters.
466CAFAE-0226-445A-9863-7665DAB99305