Frontend Web Development with Angular
Agenda Questions Some infos Lecturing Todos Router NgModules
Questions?
Some Infos Code comments from us were made for improving your code. If you ignore them you might lose points in the next sprint.
Routing & Navigation [https://angular.io/guide/router]
Today's Topics Routes Configuration Router Link Router Outlet ActivatedRoute Relative Navigation Router Events Route Guards Component-less Route
Today's Topics Routing Modules Multiple Router Outlets Optional Route Parameter Query Parameters and Fragments Asynchronous Routing Preloading
Sample Application https://gitlab.fwda.cnc.io/fwda/router
Routes Configuration Route Data Route with Parameter Child Routes Redirecting Route Wildcard Route first-match wins strategy Route data: page titles, breadcrumb text, and other read-only, static data
Routes Configuration Routes Config Print navigation lifecycle to console RouterModule.forRoot method is a pattern used to register application-wide providers
Router Link & Router Outlet Router Outlet acts as a placeholder <a routerlink="/user/bob">link to user component</a> <a [routerlink]="[ /user, bob ]">link to user component</a>
ActivatedRoute import { ActivatedRoute } from '@angular/router';... constructor(private activatedroute: ActivatedRoute) { } Important: convert param to number with + Unsubscribe from this observable? The Router destroys a routed component when it is no longer needed and the injected ActivatedRoute dies with it.
ActivatedRoute Observable parammap and component reuse The router re-uses a component instance when it re-navigates to the same component type without visiting a different component first The route parameters could change each time Eg: A parent component navigation bar had "forward" and "back" buttons that scrolled through the list of persons. Each click navigated to the detail component of a person with the next or previous id. Alternative: Use a snapshot let id = this.activatedroute.snapshot.parammap.get('id'); https://angular.io/guide/router#parammap-api
Relative Navigation Current route: localhost:5555/user/1/details <a [routerlink]="...">link to user component</a> directory-like syntax: [../ ] localhost:5555/user/1 [../../ ] localhost:5555/user [../admin ] localhost:5555/user/1/admin [./admin ] localhost:5555/user/1/details/admin [ /admin ] localhost:5555/admin
Relative Navigation import { Router, ActivatedRoute } from '@angular/router';... constructor(private router: Router, private activatedroute: ActivatedRoute){ }...
Router Events https://angular.io/guide/router#router-events
Route Guards The user is not authorized to navigate to the target component The user must login first CanActivate, CanActivateChild Fetch some data before you display the target component Resolve Save pending changes before leaving a component CanDeactivate Ask the user if it's OK to discard pending changes rather than save them
Route Guards Multiple guards at every level of a routing hierarchy The router checks the CanDeactivate and CanActivateChild guards first, from the deepest child route to the top Then it checks the CanActivate guards from the top down to the deepest child route Return value of a guard controls the routing behavior True Navigation process continues False Navigation process stops and the user stays put Pending guards that have not completed will be canceled, and the entire navigation is canceled
Route Guards
Route Guards
Route Guards CanActivate CanDeactivate
Route Guards CanActivateChild Resolve
Route Guards The guard can also cancel the navigation and tell router to navigate elsewhere Requires an Observable to complete, meaning it has emitted all of its values Note: The observable provided to the Router must also complete. If the observable does not complete, the navigation will not continue. http://rxmarbles.com/#first
Route Guards Guards and the service providers they require must be provided at the module-level Router can retrieve these services from the injector during the navigation process Same rule applies for feature modules loaded asynchronously @Injectable() export class PermissionGuard implements CanActivate { } constructor(private personservice: PersonService) { } @NgModule({ declarations: [...], imports: [...], providers: [ PersonService,... ], bootstrap: [...] }) export class AppModule {}
Component-less Route Grouping routes Makes it easier to guard child routes
Routing Modules Separates routing concerns from other application concerns Provides a module to replace or remove when testing the application Provides a well-known location for routing service providers including guards and resolvers Does not declare components!
Routing Modules Order! By re-exporting the RouterModule here the components declared in AppModule will have access to router directives such as RouterLink and RouterOutlet.
Routing Modules really necessary? Advice from the Angular Team: Choose one pattern or the other and follow that pattern consistently.
Multiple Router Outlets The router only supports one primary unnamed outlet per template A template can also have any number of named outlets Each named outlet has its own set of routes with their own components Multiple outlets can be displaying different content, determined by different routes, all at the same time Named outlets are the targets of secondary routes Eg: Pop-Up
Multiple Router Outlets & Secondary Routes Secondary routes look like primary routes and you can configure them the same way. They are independent of each other They work in combination with other routes Route: http://localhost:4200/persons(popup:popup)
Route Parameter Required URL Parameter (as placeholder in the route) Optional URL Parameters (matrix URL notation) Query Parameters Fragment
Optional Route Parameter Optional route parameters are not separated by "?" or "&" as they would be in the URL query string Separated by semicolons ";" Matrix URL notation Eg. localhost:4200/persons;id=15;foo=bar
Query Parameters and Fragments Fragments refer to certain elements on the page identified with an id attribute http://localhost:4200/permission-denied?errorcode=1234#permission More information about query parameter handling and preserving of query parameter and fragments: https://angular.io/api/router/navigationextras
Sample Application https://gitlab.fwda.cnc.io/fwda/ng-modules
Lazy Loading with the Router At the moment: AdminModule is loaded when the application starts Eager loading Means that all modules are loaded when the app launches What we want: AdminModule loads only when the user clicks on a link Lazy loading
Lazy Loading with the Router Load feature modules lazily, on request Multiple benefits Load feature areas only when requested by the user Speed up load time for users that only visit certain areas of the app
Lazy Loading with the Router Provided services in a lazy-loaded module are only visible to that module Module-scoped Router lazy-loads a module it creates a new execution context Context has its own injector Child injector Direct child of the root injector Providers of a lazy module and the providers of its imported modules are added to the child injector
Lazy Loading with the Router Root Injector AppModule Router lazy-loads a module PersonModule Child Injector Child Injector AdminModule
Lazy Loading with the Router Guard lazy loaded modules with a CanLoad guard CanLoad guard is checked before the module is loaded
Lazy Loading with the Router CanLoad guard use case: You are already protecting the AdminModule with a CanActivate guard that prevents unauthorized users from accessing the admin feature area. It will redirect the user to the login page if the user is not authorized. But the router is still loading the AdminModule even if the user can't visit any of its components. Ideally, you'd only load the AdminModule if the user is logged in. Use CanLoad guard
Routing vs Routed Modules Routed Modules Domain feature modules whose top components are the targets of routes Lazy-loaded modules Don t export anything because their components never appear in the template of another component Should not be imported by any module Would trigger an eager load Routing Modules Provides routing configuration for another module Separates routing concerns from its companion module https://angular.io/guide/module-types
Preloading After each successful navigation Router looks in its configuration for an unloaded module that it can preload Preloading depends on preloading strategy Preloading strategies None (Default) Preload all Modules Custom Preloading Strategy Custom Preloading Strategy: https://angular.io/guide/router#custom-preloading-strategy https://vsavkin.com/angular-router-preloading-modules-ba3c75e424cb
Preloading PreloadAllModules strategy does not load feature areas protected by a CanLoad guard Want to preload a module and guard against unauthorized access, drop the CanLoad guard and use the CanActivate guard alone
Thank you for your attention! Questions?
Todos Refactor code based on suggestions and code comments Finish 3nd Sprint