Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Advanced Routing @AngularDays Spring 2022
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Manfred Steyer
PRO
March 23, 2022
Programming
1
220
Advanced Routing @AngularDays Spring 2022
Manfred Steyer
PRO
March 23, 2022
Tweet
Share
More Decks by Manfred Steyer
See All by Manfred Steyer
Premier Disciplin for Micro Frontends Multi Version/ Framework Scenarios @OOP 2026, Munic
manfredsteyer
PRO
0
82
Beyond the Basics: Signal Forms
manfredsteyer
PRO
0
61
360° Signals in Angular: Signal Forms with SignalStore & Resources @ngLondon 01/2026
manfredsteyer
PRO
0
130
All About Angular‘s New Signal Forms
manfredsteyer
PRO
0
28
Full-Cycle Reactivity in Angular: SignalStore mit Signal Forms und Resources
manfredsteyer
PRO
0
260
Your Architecture as a Crime Scene?Forensic Analysis
manfredsteyer
PRO
0
180
Full-Cycle Reactivity in Angular: SignalStore mit Signal Forms und Resources
manfredsteyer
PRO
0
280
Your Architecture as a Crime Scene:Forensic Analysis
manfredsteyer
PRO
0
130
Reactive Thinking with Signals and the new Resource API
manfredsteyer
PRO
0
250
Other Decks in Programming
See All in Programming
Rust 製のコードエディタ “Zed” を使ってみた
nearme_tech
PRO
0
210
Package Management Learnings from Homebrew
mikemcquaid
0
230
KIKI_MBSD Cybersecurity Challenges 2025
ikema
0
1.3k
そのAIレビュー、レビューしてますか? / Are you reviewing those AI reviews?
rkaga
6
4.6k
Lambda のコードストレージ容量に気をつけましょう
tattwan718
0
140
インターン生でもAuth0で認証基盤刷新が出来るのか
taku271
0
190
なるべく楽してバックエンドに型をつけたい!(楽とは言ってない)
hibiki_cube
0
140
生成AIを活用したソフトウェア開発ライフサイクル変革の現在値
hiroyukimori
PRO
0
100
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
610
生成AIを使ったコードレビューで定性的に品質カバー
chiilog
1
280
今こそ知るべき耐量子計算機暗号(PQC)入門 / PQC: What You Need to Know Now
mackey0225
3
380
OCaml 5でモダンな並列プログラミングを Enjoyしよう!
haochenx
0
140
Featured
See All Featured
Designing for Timeless Needs
cassininazir
0
130
The Spectacular Lies of Maps
axbom
PRO
1
530
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
190
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.1k
The Pragmatic Product Professional
lauravandoore
37
7.1k
Bash Introduction
62gerente
615
210k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.4k
Visualization
eitanlees
150
17k
Faster Mobile Websites
deanohume
310
31k
Bootstrapping a Software Product
garrettdimon
PRO
307
120k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
67
The Curse of the Amulet
leimatthew05
1
8.7k
Transcript
@ManfredSteyer Advanced Routing Manfred Steyer ANGULARarchitects.io ManfredSteyer
@ManfredSteyer Routen sind der Dreh- und Angelpunkt Ihrer Angular-Anwendung!
@ManfredSteyer Inhalt • Basics: Kurze Wiederholung • Hierarchisches Routing •
Aux Routes • Guards • Resolver • Router Events • Lazy Loading und Preloading Page ▪ 3
@ManfredSteyer Manfred Steyer
@ManfredSteyer Angular Router Page ▪ 5
@ManfredSteyer Routing in Angular Page ▪ 6 Logo + Menü
Menü 2 Fußzeile SPA Platzhalter
@ManfredSteyer Routing in Angular Page ▪ 7 Logo + Menü
Menü 2 Fußzeile SPA Passagier- Komponente /FlugDemo/passagier
@ManfredSteyer Konfiguration Page ▪ 13 const APP_ROUTES: Routes = [
{ path: 'home', component: HomeComponent }, { path: 'flug-suchen', component: FlugSuchenComponent } ]
@ManfredSteyer Konfiguration Page ▪ 16 // app.module.ts @NgModule({ imports: [
BrowserModule, HttpModule, FormsModule, RouterModule.forRoot(APP_ROUTES); ], […] }) export class AppModule { } Für Root-Module Für Feature-Module: forChild
@ManfredSteyer View von AppComponent Page ▪ 19 <a routerLink="/home">Home</a> <a
routerLink="/flug-suchen">Flug suchen</a> <div> <router-outlet></router-outlet> </div>
@ManfredSteyer DEMO Page ▪ 26
@ManfredSteyer Hierarchisches Routing Page ▪ 27
@ManfredSteyer Hierarchische Views Page ▪ 28 Logo + Menü Menü
2 Fußzeile SPA Platzhalter 1
@ManfredSteyer Hierarchische Views Page ▪ 29 Logo + Menü Menü
2 Fußzeile SPA /FlugDemo/flugbuchen FlugBuchen-Komponente
@ManfredSteyer Hierarchische Views Page ▪ 30 Logo + Menü Menü
2 Fußzeile SPA Optionen Platzhalter FlugBuchen-Komponente /FlugDemo/flugbuchen
@ManfredSteyer Hierarchische Views Page ▪ 31 Logo + Menü Menü
2 Fußzeile SPA Optionen Passagier- Komponente FlugBuchen-Komponente /FlugDemo/flugbuchen/passagier
@ManfredSteyer Konfiguration Page ▪ 32 const APP_ROUTES: Routes = [
{ path: 'flug-buchen', component: FlugBuchenComponent, children: [ { path: 'flug-suchen', component: FlugSuchenComponent }, […] ] } ];
@ManfredSteyer DEMO Page ▪ 33 App Home Flug buchen Flug
suchen Flug editieren Passagier suchen Ihre Buchungen
@ManfredSteyer Aux-Routes Page ▪ 36
@ManfredSteyer Aux-Routes Page ▪ 37 Logo + Menu Menu 2
Footer SPA Placeholder Named Placeholder
@ManfredSteyer Aux-Routes Page ▪ 38 Logo + Menu Menu 2
Footer SPA Flight- Component Named Placeholder /FlightApp/flights
@ManfredSteyer Aux-Routes Page ▪ 39 Logo + Menu Menu 2
Footer SPA Flight- Component Info-Component /FlightApp/flights(aux:info)
@ManfredSteyer Aux-Routes Page ▪ 40 Logo + Menu Menu 2
Footer SPA Flight- Component Modal-Component /FlightApp/flights(aux:info/modal)
@ManfredSteyer Aux-Routes Page ▪ 41 Logo + Menu Menu 2
Footer SPA Flight-Edit- Component Modal-Component /FlightApp/flights(aux:info/modal)/17
@ManfredSteyer Use Cases • Modale Dialoge • “Applets” und teilautonome
Bereiche • Commander-Style Page ▪ 42
@ManfredSteyer Platzhalter definieren Page ▪ 43 <router-outlet></router-outlet> <hr> <router-outlet name="aux"></router-outlet>
Standard-Name: primary
@ManfredSteyer Konfiguration Page ▪ 44 export const ROUTE_CONFIG: Routes =
[ { path: 'home', component: HomeComponent }, { path: 'info', component: InfoComponent, outlet: 'aux' }, { path: 'dashboard', component: DashboardComponent, outlet: 'aux' } ]
@ManfredSteyer Aux-Routes routen Page ▪ 45 <a [routerLink]="[{outlets: { aux:
'info' }}]"> Activate Info </a> <a [routerLink]="[{outlets: { aux: null }}]"> Deactivate Info </a>
@ManfredSteyer Mehrere Outlets gleichzeitig bestücken <a [routerLink]="[{outlets: { aux: 'basket',
primary: 'flight-booking/flight-search' }}]"> … </a> <a [routerLink]="[{outlets: { aux: 'basket', primary: ['flight-booking', 'flight-search'] }}]"> … </a> <a [routerLink]="[{outlets: { aux: 'basket', primary: ['flight-booking', 'flight-edit', 17] }}]"> … </a>
@ManfredSteyer Programmatisch routen Page ▪ 47 export class AppComponent {
constructor(private router: Router) { } activateInfo() { this.router.navigate([{outlets: { aux: 'info' }}]); } deactivateInfo() { this.router.navigate([{outlets: { aux: null }}]); } }
@ManfredSteyer DEMO Page ▪ 48
@ManfredSteyer Guards Page ▪ 49
@ManfredSteyer Was sind Guards? • Services • Können Aktivierung und
Deaktivierung von Routen verhindern Page ▪ 50
@ManfredSteyer Guards Rückgabewert: boolean | Observable<boolean> | Promise<boolean> CanActivate canActivate
CanActivateChild canActivateChild CanLoad canLoad CanDeactivate<T> canDeactivate
@ManfredSteyer Guards in der Konfiguration Page ▪ 53 const APP_ROUTES:
Routes = [ { path: '/flug-buchen', component: FlugBuchenComponent, canActivate: [AuthGuard], children: [ { path: 'flug-edit/:id', component: FlugEditComponent, canDeactivate: [FlugEditGuard] }, […] ] ]
@ManfredSteyer Provider für Guards Page ▪ 56 // app.module.ts @NgModule({
providers: [ FlugEditGuard, AuthGuard ], […] }) export class AppModule { }
@ManfredSteyer DEMO Page ▪ 57
@ManfredSteyer Resolver
@ManfredSteyer Was sind Resolver? • Services • Werden beim Routenwechsel
aktiv • Verzögern Aktivierung der neuen Route • Laden benötigte Daten • Zwischenzeitlich kann z. B. Loading Indikator angezeigt werden
@ManfredSteyer Resolver @Injectable() export class FlightResolver implements Resolve<Flight> { constructor(private
flightService: FlightService) { } resolve(route, state): Observable<Flight> | Promise<Flight> | Flight { return […] } }
@ManfredSteyer Resolver registrieren const FLIGHT_BOOKING_ROUTES: Routes = [ […] {
path: 'flight-edit/:id', component: FlightEditComponent, resolve: { flight: FlightResolver } } ];
@ManfredSteyer Daten entgegennehmen @Component({ … }) export class FlightEditComponent {
flight: Flight; constructor(private route: ActivatedRoute) { } ngOnInit() { this.route.data.subscribe( data => { this.flight = data['flight']; } ); } }
@ManfredSteyer DEMO
@ManfredSteyer Lazy Loading Page ▪ 65
@ManfredSteyer Warum Lazy Loading? • Module erst bei Bedarf nachladen
• Verbesserung der Start-Performance Page ▪ 66
@ManfredSteyer Root Module mit Lazy Loading Page ▪ 67 const
APP_ROUTE_CONFIG: Routes = [ { path: '', redirectTo: 'home', pathMatch: 'full' }, { path: 'home', component: HomeComponent }, { path: 'flights', loadChildren: '[…]flight-booking.module#FlightBookingModule' } ];
@ManfredSteyer Root Module mit Lazy Loading Page ▪ 68 const
APP_ROUTE_CONFIG: Routes = [ { path: '', redirectTo: 'home', pathMatch: 'full' }, { path: 'home', component: HomeComponent }, { path: 'flights', loadChildren: () => import('[…]flight-booking.module') .then(m => m.FlightBookingModule); } ];
@ManfredSteyer Routen für Feature Module Page ▪ 69 const FLUG_ROUTES
= [ { path: '', component: FlugBuchenComponent, […] }, […] }
@ManfredSteyer Routen für Feature Module Page ▪ 70 const FLUG_ROUTES
= [ { path: 'subroute', component: FlugBuchenComponent, […] }, […] }
@ManfredSteyer DEMO Page ▪ 72
@ManfredSteyer Preloading Page ▪ 73
@ManfredSteyer Idee • Eventuell später benötigte Module werden mit freien
Ressourcen vorgeladen • Wird das Modul später tatsächlich benötigt, steht es augenblicklich zur Verfügung Page ▪ 74
@ManfredSteyer Preloading aktivieren Page ▪ 75 export const AppRoutesModule =
RouterModule.forRoot( ROUTE_CONFIG, { preloadingStrategy: PreloadAllModules });
@ManfredSteyer Problem with Lazy Loading and Classic Providers
@ManfredSteyer Lazy Loading and Shared Modules Page ▪ 89 AppModule
FlightBooking Module SharedModule includes includes (lazy) includes AuthService
@ManfredSteyer Lazy Loading and Shared Modules Page ▪ 90 AppModule
FlightBooking Module SharedModule includes includes (lazy) includes AuthService AuthService
@ManfredSteyer Lazy Loading and Shared Modules Page ▪ 91 AppModule
FlightBooking Module SharedModule includes includes (lazy) includes AuthService AuthService
@ManfredSteyer Solution 1: CoreModule Page ▪ 92 AppModule FlightBooking Module
SharedModule includes (lazy) includes CoreModule includes includes Core-Module is only imported into the AppModule Global Providers + Shell
@ManfredSteyer Solution 2: forRoot Page ▪ 93 AppModule FlightBooking Module
AuthModule includes (lazy) CoreModule
@ManfredSteyer Solution 2: forRoot Page ▪ 94 AppModule FlightBooking Module
AuthModule includes (lazy) includes (with Services) CoreModule includes includes (without Services)
@ManfredSteyer AuthModule Page ▪ 95 @NgModule({ […], providers: [] })
export class AuthModule { }
@ManfredSteyer AuthModule Page ▪ 96 @NgModule({ […], providers: [] })
export class AuthModule { static forRoot(): ModuleWithProviders<AuthModule> { return { ngModule: AuthModule, providers: [AuthService, […]] } } }
@ManfredSteyer DEMO Page ▪ 97
@ManfredSteyer Solution 3: Tree-shakable Provider Page ▪ 98 @Injectable({ providedIn:
'root' }) export class AuthService { […] }
@ManfredSteyer Tree-Shakable Provider for Lazy Modules
@ManfredSteyer Lazy Modules Page ▪ 100 @Injectable({ providedIn: LazyApiModule })
export class FlightService { […] } Only makes sense with lazy loading !! All "classic" modules: root scope Service is loaded alongside lazy module!
@ManfredSteyer Preventing Cycles
@ManfredSteyer Preventing Cycles
@ManfredSteyer DEMO
@ManfredSteyer Zusammenfassung Child Routes Aux Routes Guards Resolver Lazy Loading
& Preloading
@ManfredSteyer Kontakt and Downloads [mail]
[email protected]
[web] SOFTWAREarchitekt.at [twitter] ManfredSteyer
d Slides & Examples Public and In-House http://www.softwarearchitekt.at/workshops