Angular 2 Routing - Tuong-Nguyen/Angular-D3-Cometd GitHub Wiki
Angular Routing allows partial of the page is loaded instead of the whole page.
- Add router-outlet into the component template
@Component({
selector: "events-app",
template: `
<nav-bar></nav-bar>
<router-outlet></router-outlet>
`,
})
export class EventsAppComponent {
}
- Define routes
export const appRoutes: Routes = [
{path: "events", component: EventsListComponent },
{path: "events/:id", component: EventDetailsComponent},
{path: "", redirectTo: "events", pathMatch: "full"},
];
- Set Root routes in module file
imports: [
BrowserModule,
RouterModule.forRoot(appRoutes),
],
- Set base in index.html file (page contains the component)
<base href="/">
routerLink can be used for linking an element to a route.
<div [routerLink]="['/events', event.id]" class="well hoverwell thumbnail">
</div>
-
[routerLink]="['/events', event.id]"
<=>routerLink="{{['events', event.id]}}"
- Component can access route's parameter using ActivatedRoute instance which is injected through constructor
constructor(private route: ActivatedRoute) {}
// for route
{path: "events/:id", component: EventDetailsComponent}
// id parameter can be accessed as:
id = this.route.snapshot.params["id"];
- When route changes, we need to subscribe
params
observable to get new params
this.route.params.subscribe(
(params: Params) => {
id = params["id"];
}
)
- Angular
unsubcribe
the subscription automatically when the component is destroyed
-
queryParams
is a key-value object
<a routerLink="/users" [queryParams]="{allowEdit: '1'}">User name</a>
<!-- http://localhost:4200/users?allowEdit=1 -->
-
fragment
is string value
<a routerLink="/users" fragment="loading">User name</a>
<!-- http://localhost:4200/users#loading -->
Similar to params
, we can get queryParams
and fragment
from <ActivatedRoute>.snapshot.queryParams
and <ActivatedRoute>.snapshot.fragment
or subscribe the <ActivatedRoute>.queryParams
or <ActivatedRoute>.fragment
- Router instance can be used in Component for navigating to route
export class UsersComponent {
// inject Router instance
constructor(private router:Router){}
public cancel (){
// navigate to a route
this.router.navigate(["/users/events"]);
}
}
- To use relative route, we can add
relativeTo
a route parameter
this.router.navigate(["events"], {relativeTo: this.route})
- Use
children
property of Route
const appRoutes: Routes = [
{path: 'widgets', component: WidgetsComponent, children: [
{path: 'new', component: AddWidgetComponent}
]}
];
- In parent component's template, use
<router-outlet></router-outlet>
to load child component
- Route's canActivate property can be used for not allowing to access the route. It can be set to a service (ex: EventRouteActivator) which implement CanActivate interface.
// Service implements CanActivate interface for guarding the route
export class EventRouteActivator implements CanActivate {
constructor(private eventService: EventService, private router:Router) {}
public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
Observable<boolean> | Promise<boolean> | boolean {
let eventExist = !!this.eventService.getEvent(route.params["id"]);
if(!eventExist){
this.router.navigate(["/404"]);
}
return eventExist;
}
}
- Apply to a route
{path: "events/:id", component: EventDetailsComponent, canActivate: [EventRouteActivator]}
- Similar to
CanActivate
- Runs before any child route is activated
const adminRoutes: Routes = [
{
path: 'admin',
component: AdminComponent,
canActivate: [AuthGuard],
children: [
{
path: '',
canActivateChild: [AuthGuard],
children: [
{ path: 'heroes', component: ManageHeroesComponent },
{ path: '', component: AdminDashboardComponent }
]
}
]
}
];
export class AuthGuard implements CanActivate, CanActivateChild {
// ...
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
// implementation
}
}
Route's CanDeactivate property is used for not allowing user to move out of the route.
// Service implements CanActivate interface for guarding the route
export class EventRouteDeactivator implements CanDeactivate<Component> {
constructor(private eventService: EventService, private router:Router) {}
public canDeactivate(component: Component, route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
Observable<boolean> | Promise<boolean> | boolean {
return true;
}
}