0% found this document useful (0 votes)
15 views50 pages

Angular Router Insights and Techniques

This document discusses routing and navigation in Angular applications. It covers key routing concepts like router outlets, route resolvers, route guards, and feature modules. It shows examples of setting up routes and route configuration for components using the RouterModule and strategies for loading and resolving data before navigating to routes.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views50 pages

Angular Router Insights and Techniques

This document discusses routing and navigation in Angular applications. It covers key routing concepts like router outlets, route resolvers, route guards, and feature modules. It shows examples of setting up routes and route configuration for components using the RouterModule and strategies for loading and resolving data before navigating to routes.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd

N Things You Don’t Know

About the Router


N > 0
Deborah Kurata
Developer | Author | Consultant | MVP | GDE
@deborahkurata
How Routing Works
<a [routerLink]="['/movies']">Movie List</a>

{ path: 'movies', component: MovieListComponent }

[Link]
<router-outlet></router-outlet> import { Component } from '@angular/core';

@Component({
  templateUrl: '[Link]'
})
export class MovieListComponent { }
To Menu
or Not To Menu
[Link]
<div class="container">
<nav class="navbar navbar-default">
<div class="container-fluid">
<a class="navbar-brand">{{pageTitle}}</a>
<ul class="nav navbar-nav">
<li><a [routerLink]="['/welcome']">Home</a></li>
<li><a [routerLink]="['/movies']">Movie List</a></li>
</ul>
</div>
</nav>
<div class="container">
<router-outlet></router-outlet>
</div>
</div>
app
router outlet
[Link]
<div class="container">
<nav class="navbar navbar-default" *ngIf="displayMenu">
<div class="container-fluid">
<a class="navbar-brand">{{pageTitle}}</a>
<ul class="nav navbar-nav">
<li><a [routerLink]="['/welcome']">Home</a></li>
<li><a [routerLink]="['/movies']">Movie List</a></li>
</ul>
</div>
</nav>
<div class="container">
<router-outlet></router-outlet>
</div>
</div>
[Link]
<router-outlet></router-outlet>
app
router outlet
app
router outlet
[Link]
<div class="container">
<nav class="navbar navbar-default">
<div class="container-fluid">
<a class="navbar-brand">{{pageTitle}}</a>
<ul class="nav navbar-nav">
<li><a [routerLink]="['/welcome']">Home</a></li>
<li><a [routerLink]="['/movies']">Movie List</a></li>
</ul>
</div>
</nav>
<div class="container">
<router-outlet></router-outlet>
</div>
</div>
[Link]
<mh-menu></mh-menu>

<div class='container'>
<router-outlet></router-outlet>
</div>
app
router outlet
shell
router outlet
[Link]
[Link]([
{
path: '', component: ShellComponent,
children: [
{ path: 'welcome', component: WelcomeComponent },
{ path: 'movies', component: MovieListComponent },
{ path: '', redirectTo: 'welcome', pathMatch: 'full' }
]
},
{ path: 'login', component: LoginComponent },
{ path: '**', component: PageNotFoundComponent }
])
Preventing
Partial Page Display
Build a Resolver Service
[Link]
@Injectable()
export class MovieResolver implements Resolve<IMovie> {

constructor(private movieService: MovieService) { }

resolve(route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<IMovie> {
const id = [Link]('id');
return [Link](+id);
}
}
Register the Resolver
[Link]
providers: [
MovieService,
MovieResolver
]
Add Resolver to Route
[Link]
{
path: 'movies/:id',
resolve: { movie: MovieResolver },
component: MovieDetailComponent
},
Read Resolver Data
[Link]
ngOnInit(): void {
[Link] = [Link]['movie'];
}

[Link]
{
path: 'movies/:id',
resolve: { movie: MovieResolver },
component: MovieDetailComponent
},
I'm Waiting …
Subscribe to Router Events
[Link]
constructor(private router: Router) {
[Link]((routerEvent: Event) => {
[Link](routerEvent);
});
}
Check Router Events
[Link]
checkRouterEvent(routerEvent: Event): void {
if (routerEvent instanceof NavigationStart) {
[Link] = true;
}

if (routerEvent instanceof NavigationEnd ||


routerEvent instanceof NavigationCancel ||
routerEvent instanceof NavigationError) {
[Link] = false;
}
}
Display the Spinner
[Link]
<span class="glyphicon glyphicon-refresh glyphicon-spin spinner"
*ngIf="loading"></span>
<router-outlet></router-outlet>
What’s going on?
[Link]
[Link]([
{
path: '', component: ShellComponent,
children: [
{ path: 'welcome', component: WelcomeComponent },
{ path: 'movies', component: MovieListComponent },
{ path: '', redirectTo: 'welcome', pathMatch: 'full' }
]
},
{ path: 'login', component: LoginComponent },
{ path: '**', component: PageNotFoundComponent }
], { enableTracing: true })
Guards at the Ready
Build a Guard Service
[Link]
@Injectable()
export class MovieEditGuard implements
CanDeactivate<MovieEditComponent> {

canDeactivate(component: MovieEditComponent): boolean {


if ([Link]) {
const title = [Link] || 'New Movie';
return confirm(`Lose all changes to ${title}?`);
}
return true;
}
}
Register the Guard
[Link]
providers: [
MovieService,
MovieResolver,
MovieEditGuard
]
Add Guard to Route
[Link]
{
path: 'movies/:id/edit',
resolve: { movie: MovieResolver },
canDeactivate: [ MovieEditGuard ],
component: MovieEditComponent
}
Keep Constant
[Link]
@NgModule({
imports: [
[Link]([
{
path: '', component: ShellComponent,
children: [
{ path: 'welcome', component: WelcomeComponent },
{ path: 'movies', component: MovieListComponent },
{ path: 'movies/:id', component: MovieDetailComponent },
{
path: 'movies/:id/edit', component: MovieEditComponent,
children: [
{ path: '', redirectTo: 'info', pathMatch: 'full' },
{ path: 'info', component: MovieEditInfoComponent },
{ path: 'tags', component: MovieEditTagsComponent }
]
},
{ path: '', redirectTo: 'welcome', pathMatch: 'full' }
]
},
{ path: 'login', component: LoginComponent },
{ path: '**', component: PageNotFoundComponent }
])
],
exports: [RouterModule]
})
export class AppRoutingModule { }
[Link]
const appRoutes: Routes = [
{
path: '', component: ShellComponent,
children: [
{ path: 'welcome', component: WelcomeComponent },
{ path: 'movies', component: MovieListComponent },
{ path: 'movies/:id', component: MovieDetailComponent },
{ path: 'movies/:id/edit', component: MovieEditComponent,
children: [
{ path: '', redirectTo: 'info', pathMatch: 'full' },
{ path: 'info', component: MovieEditInfoComponent },
{ path: 'tags', component: MovieEditTagsComponent }
]
},
{ path: '', redirectTo: 'welcome', pathMatch: 'full' }
]
},
{ path: 'login', component: LoginComponent },
{ path: '**', component: PageNotFoundComponent }
];
[Link]

@NgModule({
imports: [
[Link](appRoutes)
],
exports: [RouterModule]
})
export class AppRoutingModule { }
It’s a Feature
What About Feature Modules?
[Link]
const appRoutes: Routes = [
{
path: '', component: ShellComponent,
children: [
{ path: 'welcome', component: WelcomeComponent },
{ path: 'movies', component: MovieListComponent },
{ path: 'movies/:id', component: MovieDetailComponent },
{ path: 'movies/:id/edit', component: MovieEditComponent,
children: [
{ path: '', redirectTo: 'info', pathMatch: 'full' },
{ path: 'info', component: MovieEditInfoComponent },
{ path: 'tags', component: MovieEditTagsComponent }
]
},
{ path: '', redirectTo: 'welcome', pathMatch: 'full' }
]
},
{ path: 'login', component: LoginComponent },
{ path: '**', component: PageNotFoundComponent }
];
[Link]
const movieRoutes: Routes = [
{ path: 'movies', component: MovieListComponent } ,
{ path: 'movies/:id', component: MovieDetailComponent },
{ path: 'movies/:id/edit', component: MovieEditComponent,
children: [
{ path: '', redirectTo: 'info', pathMatch: 'full' },
{ path: 'info', component: MovieEditInfoComponent },
{ path: 'tags', component: MovieEditTagsComponent }
]
}
];

@NgModule({
imports: [ ...,
[Link](movieRoutes) // Won’t work!
], ...
})
export class MovieModule { }
imports: [
MovieModule, Merged Routes
[Link](appRoutes)
] { path: 'movies', component: MovieListComponent } ,
{ path: 'movies/:id', component: MovieDetailComponent },
{ path: 'movies/:id/edit', component: MovieEditComponent,
children: [
{ path: '', redirectTo: 'info', pathMatch: 'full' },
{ path: 'info', component: MovieEditInfoComponent },
{ path: 'tags', component: MovieEditTagsComponent }
]
}
{ path: '', component: ShellComponent,
children: [
{ path: 'welcome', component: WelcomeComponent },
{ path: '', redirectTo: 'welcome', pathMatch: 'full' }
]
},
{ path: 'login', component: LoginComponent },
{ path: '**', component: PageNotFoundComponent }
Lazy Loading
From: Angular Routing course on Pluralsight
loadChildren
[Link]
{
path: '', component: ShellComponent,
children: [
{ path: 'welcome', component: WelcomeComponent },
{
path: 'movies',
loadChildren: './movies/[Link]#MovieModule'
},
{ path: '', redirectTo: 'welcome', pathMatch: 'full' }
]
},
{ path: 'login', component: LoginComponent },
{ path: '**', component: PageNotFoundComponent }
[Link]
const movieRoutes: Routes = [
{ path: '', component: MovieListComponent } ,
{ path: ':id', component: MovieDetailComponent },
{ path: ':id/edit', component: MovieEditComponent,
children: [
{ path: '', redirectTo: 'info', pathMatch: 'full' },
{ path: 'info', component: MovieEditInfoComponent },
{ path: 'tags', component: MovieEditTagsComponent }
]
}
];

@NgModule({
imports: [ ...,
[Link](movieRoutes)
], ...
})
export class MovieModule { }
For More Information

Twitter: @deborahkurata
Code: [Link]
routing
Slides: [Link]/ngConf18
Course: [Link]/Angular-routing

You might also like