Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Der Angular Router im Detail betrachtet

Der Angular Router im Detail betrachtet

Talk from AngularDays in Berlin (Germany), October 2017

Manfred Steyer

October 10, 2017
Tweet

More Decks by Manfred Steyer

Other Decks in Programming

Transcript

  1. Über mich … • Manfred Steyer • SOFTWAREarchitekt.at • Trainer

    & Consultant • Focus: Angular • Gründer: angular-akademie.com • Google Developer Expert (GDE) Page ▪ 2 Manfred Steyer
  2. Inhalt • Basics zu Routing • Child-Routes • Aux-Routes •

    Guards • Resolver • Lazy Loading • Preloading Page ▪ 4
  3. Routing unter Angular Page ▪ 9 Logo + Menü Menü

    2 Fußzeile SPA Passagier- Komponente /FlugDemo#passagier
  4. Routen via History API • /FlugDemo/passagier • Gesamte Url wird

    zum Server gesendet • Server antwortet mit SPA • Server kann erste Ansicht "vorrendern" • Performance, SEO, … • SPA informiert Browser über Grenze zwischen (eigentlicher) Url und Route Page ▪ 11
  5. Konfiguration Page ▪ 13 const APP_ROUTES: Routes = [ {

    path: 'home', component: HomeComponent }, { path: 'flug-suchen', component: FlugSuchenComponent } ]
  6. Konfiguration Page ▪ 14 const APP_ROUTES: Routes = [ {

    path: '', redirectTo: 'home', pathMatch: 'full' }, { path: 'home', component: HomeComponent }, { path: 'flug-suchen', component: FlugSuchenComponent } ]
  7. Konfiguration Page ▪ 15 const APP_ROUTES: Routes = [ {

    path: '', redirectTo: 'home', pathMatch: 'full' }, { path: 'home', component: HomeComponent }, […] { path: '**', redirectTo: 'home' } ]
  8. Konfiguration Page ▪ 16 // app.module.ts @NgModule({ imports: [ BrowserModule,

    HttpModule, FormsModule, RouterModule.forRoot(ROUTE_CONFIG) ], […] }) export class AppModule { } Für Root-Module Für Feature-Module: forChild
  9. Konfiguration Page ▪ 22 const APP_ROUTES: Routes = [ […]

    { path: 'flug-suchen', component: FlugSuchenComponent }, { path: 'flug-edit/:id', component: FlugEditComponent } }
  10. Parameter auslesen Page ▪ 23 export class FlugEditComponent { public

    id: string; constructor( private route: ActivatedRoute) { route.params.subscribe( p => { this.id = p['id']; […] } ); } […] }
  11. DEMO Page ▪ 25 App Home Search Flight Edit Flight

    Search Passenger Your Bookings FlightBookingModule AppModule
  12. Hierarchische Views Page ▪ 28 Logo + Menü Menü 2

    Fußzeile SPA /FlugDemo/flugbuchen FlugBuchen-Komponente
  13. Hierarchische Views Page ▪ 29 Logo + Menü Menü 2

    Fußzeile SPA /FlugDemo/flugbuchen Optionen Platzhalter FlugBuchen-Komponente
  14. Hierarchische Views Page ▪ 30 Logo + Menü Menü 2

    Fußzeile SPA Optionen Passagier- Komponente FlugBuchen-Komponente /FlugDemo/flugbuchen/passagier
  15. Konfiguration Page ▪ 31 const APP_ROUTES: Routes = [ {

    path: '', component: HomeComponent, pathMatch: 'full' }, { path: 'flug-buchen', component: FlugBuchenComponent, children: [ { path: 'flug-suchen', component: FlugSuchenComponent }, […] ] } ];
  16. DEMO Page ▪ 32 App Home Flight- Booking Search Flight

    Edit Flight Search Passenger Your Bookings
  17. Aux-Routes Page ▪ 36 Logo + Menu Menu 2 Footer

    SPA Placeholder Named Placeholder
  18. Aux-Routes Page ▪ 37 Logo + Menu Menu 2 Footer

    SPA Flight- Component Named Placeholder /FlightApp/flights
  19. Aux-Routes Page ▪ 38 Logo + Menu Menu 2 Footer

    SPA Flight- Component Info-Component /FlightApp/flights(aux:info)
  20. Aux-Routes Page ▪ 39 Logo + Menu Menu 2 Footer

    SPA Flight- Component Modal-Component /FlightApp/flights(aux:info/modal)
  21. Aux-Routes Page ▪ 40 Logo + Menu Menu 2 Footer

    SPA Flight-Edit- Component Modal-Component /FlightApp/flights(aux:info/modal)/17
  22. Konfiguration Page ▪ 43 export const ROUTE_CONFIG: Routes = [

    { path: 'home', component: HomeComponent }, { path: 'info', component: InfoComponent, outlet: 'aux' }, { path: 'dashboard', component: DashboardComponent, outlet: 'aux' } ]
  23. Aux-Routes routen Page ▪ 44 <a [routerLink]="[{outlets: { aux: 'info'

    }}]"> Activate Info </a> <a [routerLink]="[{outlets: { aux: null }}]"> Deactivate Info </a>
  24. Aux-Routes routen Page ▪ 45 <a [routerLink]="[{outlets: { aux: 'info',

    primary: 'flight-search' }}]"> Activate Info </a> <a [routerLink]="[{outlets: { aux: null }}]"> Deactivate Info </a>
  25. Programmatisch routen Page ▪ 46 export class AppComponent { constructor(private

    router: Router) { } activateInfo() { this.router.navigate([{outlets: { aux: 'info' }}]); } deactivateInfo() { this.router.navigate([{outlets: { aux: null }}]); } }
  26. Was sind Guards? • Services • Werden beim Aktivieren bzw.

    Deaktivieren einer Route aktiv • Können Aktivierung und Deaktivierung verhindern Page ▪ 49
  27. Guards in der Konfiguration Page ▪ 52 const APP_ROUTES: Routes

    = [ { path: '/flug-buchen', component: FlugBuchenComponent, canActivate: [AuthGuard], children: [ { path: 'flug-edit/:id', component: FlugEditComponent, canDeactivate: [FlugEditGuard] }, […] ] ] Token
  28. Provider für Guards Page ▪ 53 // app.module.ts @NgModule({ providers:

    [ { provide: FlugEditGuard, useClass: AdvFlightEditGuard } { provide: AuthGuard, useClass: AdvAuthGuard } ], […] }) export class AppModule { }
  29. Provider für Guards Page ▪ 54 // app.module.ts @NgModule({ providers:

    [ FlugEditGuard, AuthGuard ], […] }) export class AppModule { }
  30. Was sind Resolver? • Services • Werden beim Routenwechsel aktiv

    • Laden benötigte Daten • Verzögern Aktivierung der neuen Route • Zwischenzeitlich kann z. B. Loading Indikator angezeigt werden
  31. Resolver @Injectable() export class FlightResolver implements Resolve<Flight> { constructor(private flightService:

    FlightService) { } resolve(route, state): Observable<Flight> | Promise<Flight> | Flight { return […] } }
  32. Resolver registrieren const FLIGHT_BOOKING_ROUTES: Routes = [ […] { path:

    'flight-edit/:id', component: FlightEditComponent, resolve: { flight: FlightResolver } } ]; Token
  33. Daten entgegennehmen @Component({ … }) export class FlightEditComponent { flight:

    Flight; constructor(private route: ActivatedRoute) { } ngOnInit() { this.route.data.subscribe( data => { this.flight = data['flight']; } ); } }
  34. Warum Lazy Loading? • Module erst bei Bedarf nachladen •

    Verbesserung der Start-Performance Page ▪ 64
  35. Root Module mit Lazy Loading Page ▪ 65 const APP_ROUTE_CONFIG:

    Routes = [ { path: '', redirectTo: 'home', pathMatch: 'full' }, { path: 'home', component: HomeComponent }, { path: 'flights', loadChildren: '[…]flight-booking.module#FlightBookingModule' } ];
  36. Routen für Feature Module Page ▪ 66 const FLUG_ROUTES =

    [ { path: '', component: FlugBuchenComponent, […] }, […] } export const FlugRouterModule = RouterModule.forChild(FLUG_ROUTES);
  37. 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 ▪ 69
  38. Preloading aktivieren Page ▪ 70 export const AppRoutesModule = RouterModule.forRoot(

    ROUTE_CONFIG, { preloadingStrategy: PreloadAllModules });
  39. Lazy Loading und Shared Modules Page ▪ 73 AppModule FlugModule

    SharedModule includes includes (lazy) includes
  40. Lazy Loading und Shared Modules Page ▪ 74 AppModule FlugModule

    SharedModule includes includes (lazy) includes AuthService AuthService
  41. Lazy Loading und Shared Modules Page ▪ 75 AppModule FlugModule

    SharedModule includes includes (lazy) includes AuthService AuthService
  42. Lösung Page ▪ 76 AppModule FlugModule SharedModule includes (lazy) includes

    CoreModule includes includes Core-Module soll nur ins AppModule eingebunden werden Globale Provider, wie AuthService & Shell
  43. Lösung (für Libraries) Page ▪ 79 AppModule FlugModule AuthModule includes

    (lazy) includes (mit Services) CoreModule includes includes (ohne Services) Shell
  44. AuthModule Page ▪ 82 @NgModule({ […], providers: [] }) export

    class AuthModule { static forRoot(): ModuleWithProviders { return { ngModule: AuthModule, providers: [AuthService, […]] } } }