-
Notifications
You must be signed in to change notification settings - Fork 202
Commit
Add documenatation on RouterLayout functionality. Update source samples and add reference links. Closes #3819
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,27 +9,37 @@ order: 40 | |
|
||
= Router Layouts & Nested Router Targets | ||
|
||
All parent layouts of a navigation target component have to implement the [interfacename]`RouterLayout` interface. You can define a parent layout by adding the [annotationname]`@Layout` annotation to the class, or by using the optional element `layout` from the `@Route` annotation. | ||
All parent layouts of a navigation target component have to implement the [interfacename]`RouterLayout` interface. | ||
You can define a parent layout by adding the [annotationname]`@Layout` annotation to the class, or by using the optional element `layout` from the `@Route` annotation. | ||
|
||
[interfacename]`RouterLayout` interface automatically appends and removes child route content during navigation. For more indepth information see <<#Router Layout,Router Layout>>. | ||
Check failure on line 15 in articles/flow/routing/layout.adoc GitHub Actions / lint
|
||
|
||
|
||
[role="since:com.vaadin:[email protected]"] | ||
=== Automatic Layout Using `@Layout` | ||
|
||
The value for the [annotationName]`@Layout` annotation path has to be unique for the project. Otherwise, the resolver won't be able to determine which layout component should be used. Having multiple [annotationName]`@Layout` annotations with the same path throws an exception. | ||
The [annotationName]`@Layout` can be put on any [className]`Component` that implements [interfacename]`RouterLayout`. | ||
|
||
The example below renders all routes inside [classname]`MainLayout`: | ||
|
||
[source,java] | ||
---- | ||
@Layout | ||
public class MainLayout extends Div | ||
implements RouterLayout { | ||
public class MainLayout extends AppLayout { | ||
} | ||
---- | ||
|
||
If the application is using access protection, the view access is checked for the Layout, as well as the view. To make the layout accessible, add [annotationname]`@AnonymousAllowed` -- or some other access annotation -- on the `MainLayout` so that the request is not denied. | ||
See <<{articles}/components/app-layout/#,AppLayout>> for more information on usage. | ||
Check failure on line 32 in articles/flow/routing/layout.adoc GitHub Actions / lint
|
||
|
||
The value for the [annotationName]`@Layout` annotation path has to be unique for the project. Otherwise, the resolver won't be able to determine which layout component should be used. | ||
Having multiple [annotationName]`@Layout` annotations with the same path throws an exception. | ||
|
||
If the application is using access protection, the view access is checked for the Layout, as well as the view. | ||
To make the layout accessible, add [annotationname]`@AnonymousAllowed` -- or some other access annotation -- on the `MainLayout` so that the request is not denied. | ||
|
||
[annotationname]`@Route` and [annotationname]`@RouteAlias` each contain an annotation attribute called, `autoLayout`. Setting that attribute to false will stop automatic layout; it will ignore any [annotationname]`@Layout` matching the route. Giving a class for the `layout` method in [annotationname]`@Route` also disables automatic layout and uses the one given. | ||
[annotationname]`@Route` and [annotationname]`@RouteAlias` each contain an annotation attribute called, `autoLayout`. | ||
Setting that attribute to false will stop automatic layout; it will ignore any [annotationname]`@Layout` matching the route. | ||
Check warning on line 41 in articles/flow/routing/layout.adoc GitHub Actions / lint
Check warning on line 41 in articles/flow/routing/layout.adoc GitHub Actions / lint
|
||
Giving a class for the `layout` method in [annotationname]`@Route` also disables automatic layout and uses the one given. | ||
|
||
.Ignore Automatic Layout | ||
[source,java] | ||
|
@@ -87,19 +97,18 @@ See <<page-titles#,Updating Page Title on Navigation>> for more information on t | |
|
||
Use the `@ParentLayout` annotation to define a parent layout for components in the routing hierarchy. Where necessary, a parent can have its own parent layout. | ||
|
||
In the example below, `MainLayout` is used for everything, which `MenuBar` is reused for views: | ||
In the example below, `MainLayout` is used for everything, and `SubMenu` is reused for views: | ||
|
||
[source,java] | ||
---- | ||
public class MainLayout extends Div | ||
implements RouterLayout { | ||
public class MainLayout extends AppLayout { | ||
} | ||
@Layout | ||
@ParentLayout(MainLayout.class) | ||
public class MenuBar extends Div | ||
public class SubMenu extends Div | ||
implements RouterLayout { | ||
public MenuBar() { | ||
public SubMenu() { | ||
addMenuElement(TutorialView.class, "Tutorial"); | ||
addMenuElement(IconsView.class, "Icons"); | ||
} | ||
|
@@ -119,7 +128,7 @@ public class IconsView extends Div { | |
} | ||
---- | ||
|
||
`MainLayout` encapsulates `MenuBar`, which in turn encapsulates `TutorialView` or `IconsView` -- depending on where the user has navigated. | ||
`MainLayout` encapsulates `SubMenu`, which in turn encapsulates `TutorialView` or `IconsView` -- depending on where the user has navigated. | ||
|
||
|
||
== ParentLayout Route Control | ||
|
@@ -181,4 +190,103 @@ The bound route is `framework/tutorial`, although the full chain is `some/framew | |
|
||
If a parent layout defines a `@RoutePrefix`, the "default" child could have its route defined as `@Route("")` and be mapped to the parent layout route. For example, `Tutorials` with route `""` would be mapped as `framework/`. | ||
|
||
|
||
=== Router Layout | ||
|
||
A class implementing the [interfacename]`RouterLayout` interface will automatically append and remove content on navigation to a route with the layout in the parent stack. | ||
Check warning on line 196 in articles/flow/routing/layout.adoc GitHub Actions / lint
|
||
|
||
By default, the content will be appended to the [interfacename]`RouterLayout` component, so anything added on navigation will be positioned last. | ||
Check warning on line 198 in articles/flow/routing/layout.adoc GitHub Actions / lint
Check warning on line 198 in articles/flow/routing/layout.adoc GitHub Actions / lint
|
||
|
||
.Layout Order Sample | ||
[source,java] | ||
---- | ||
public class ParentLayout extends Div implements RouterLayout { | ||
public ParentLayout() { | ||
add(new Span("Parent content")); | ||
} | ||
} | ||
@Route(value = "route", layout = ParentLayout.class) | ||
public class MyRoute extends Div { | ||
public MyRoute() { | ||
add(new Span("View content")); | ||
} | ||
} | ||
---- | ||
|
||
.Sample Output | ||
[source,text] | ||
---- | ||
Parent content | ||
View content | ||
---- | ||
|
||
Adding elements after navigation in the parent will put the content after the view content. | ||
Check warning on line 224 in articles/flow/routing/layout.adoc GitHub Actions / lint
|
||
|
||
.Layout Order Sample | ||
[source,java] | ||
---- | ||
public class ParentLayout extends Div implements RouterLayout { | ||
public ParentLayout() { | ||
add(new Span("Parent content")); | ||
} | ||
@Override | ||
protected void onAttach(AttachEvent attachEvent) { | ||
add(new Span("On attach")); | ||
} | ||
} | ||
@Route(value = "route", layout = ParentLayout.class) | ||
public class MyRoute extends Div { | ||
public MyRoute() { | ||
add(new Span("View content")); | ||
} | ||
} | ||
---- | ||
|
||
.Sample Output | ||
[source,text] | ||
---- | ||
Parent content | ||
View content | ||
On attach | ||
---- | ||
|
||
To customise content position the method [methodname]`showRouterLayoutContent(HasElement content)` can be overridden. | ||
Even with [methodname]`showRouterLayoutContent` overridden the content will be automatically removed from the component on navigation if not part of the new route. | ||
Check warning on line 257 in articles/flow/routing/layout.adoc GitHub Actions / lint
|
||
|
||
.Custom Content Sample | ||
[source,java] | ||
---- | ||
public class ParentLayout extends Div implements RouterLayout { | ||
private Div childHolder = new Div(); | ||
public ParentLayout() { | ||
add(childHolder, new Span("Parent content")); | ||
} | ||
@Override | ||
public void showRouterLayoutContent(HasElement content) { | ||
if(content != null) { | ||
childHolder.getElement().appendChild(content.getElement()); | ||
} | ||
} | ||
} | ||
@Route(value = "route", layout = ParentLayout.class) | ||
public class MyRoute extends Div { | ||
public MyRoute() { | ||
add(new Span("View content")); | ||
} | ||
} | ||
---- | ||
|
||
.Sample Output | ||
[source,text] | ||
---- | ||
View content | ||
Parent content | ||
---- | ||
|
||
[discussion-id]`7A96749F-CD19-4422-A2A2-B4ACD719C9FA` |