Navigation is probably the most important feature of a Router, we will have a look are our options to navigate from a Component route to another and pass data to your component through the URL.
First, let's consider the followings RoutePath
definitions.
import 'package:angular/angular.dart';
import 'package:angular_router/angular_router.dart';
class AppRoutes {
static final list = RoutePath(path: 'list');
}
final routes = <RouteDefinition>[
RouteDefinition(
routePath: AppRoutes.list,
component: ng.ListComponentNgFactory,
),
];
Basic navigation
You can simply use the navigate
method from the Router and defined RoutePath to build the URL you want to navigate to.
@Component(
selector: 'nav-bar',
template: '''
<div (click)="navigateToList()">List</div>
''',
)
class NavBarComponent {
final Router router;
NavBarComponent(this.router);
void navigateToList() {
router.navigate(AppRoutes.list.toUrl());
}
}
It works but, you are not really following HTML semantics. To navigate between pages you should be using an Anchor element and set href
attribute on it.
However, if you try to set it manually as follow.
<a [attr.href]="AppRoutes.list.toUrl()">List</a>
It won't always work since the element is not aware of your LocationStrategy
and your <base href="...">
configuration.
To set the URL on an anchor, angular provides the RouterLink
directive that you can use as a replacement of the href
attribute.
<a [routerLink]="AppRoutes.list.toUrl()">List</a>
As a bonus, you will be able to use the RouterLinkActive
directive to apply CSS class to your element if the URL is currently active.
<a [routerLink]="AppRoutes.list.toUrl()"
routerLinkActive="my-class">
List
</a>
Navigate with parameters
2 types of parameters are available.
The first one, simply calls parameters
could be considered as required parameters, that must be predefined in the RoutePath
definition.
class AppRoutes {
...
/// required parameter with name 'idemId'
static final listItem = RoutePath(path: 'list/:itemId');
}
final routes = <RouteDefinition>[
...
RouteDefinition(
routePath: AppRoutes.listItem,
component: ng.ListItemComponentNgFactory,
),
];
The second one, queryParameters
are mostly optional parameters, in the URL, this is everything that comes after ?
and separated by &
. (ex: example.com?foo=bar&val=42
)
Now, imagine you want to navigate to a specific list item and you also want to pass an optional value to the ListItemComponent
to make a feature visible or not for example. You just need to use available parameters of the RoutePath.toUrl
method.
/// can be use with RouterLink directive
String buildListItemUrl(String id) {
return AppRoutes.listItem.toUrl(
parameters: { 'itemId': id },
queryParameters: { 'showAwesomeFeature': 'true' },
);
}
// or
void navigateToListItem(String id) {
router.navigate(buildListItemUrl(id));
}
Both parameters must be strict
Map<String, String>
objects. if you want to pass complex data, you must have a way to encode/decode it.
Read URL parameters
Now that you know how to build URLs and trigger navigation to the route component. You probably want to access the info you stored in the URL.
To do so, you need to implement the OnActivate
provided by Angular on your component.
import 'package:angular/angular.dart';
import 'package:angular_router/angular_router.dart';
@Component(
...
)
class ListItemComponent implements OnActivate {
@override
void onActivate(RouterState previous, RouterState current) { ... }
}
Each time the router navigates to this component, the onActivate
method is called and gives you access to the previous and the current RouterState
containing both parameters that you can decode.
void onActivate(RouterState previous, RouterState current) {
final listItemId = current.parameters['itemId'];
fetchItem(listItemId);
showAwesomeFeature = current.queryParameters['showAwesomeFeature'] == 'true';
}
Top comments (0)