import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; ... const appRoutes: Routes = [...]; @NgModule({ imports: [RouterModule.forRoot(appRoutes)], exports: [RouterModule] }) export class AppRoutingModule { }importing modules avoids the need to explicitly import the needed types individually
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; ... const recipesRoutes: Routes = [ { path: 'recipes', component: RecipesComponent, children: [ { path: '', component: RecipeStartComponent }, { path: 'new', component: RecipeEditComponent, canActivate: [AuthGuard] }, // paths without dynamic IDs must be first { path: ':id', component: RecipeDetailComponent }, { path: ':id/edit', component: RecipeEditComponent, canActivate: [AuthGuard] }, ] }, ]; @NgModule({ imports: [RouterModule.forChild(recipesRoutes)], exports: [RouterModule] }) export class RecipesRoutingModule { }in the recipes.module import the new module and add it to the NgModule's imports property
... import { RecipesRoutingModule } from './recipes-routing.module'; @NgModule({ declarations: [ ... ], imports: [ ..., RecipesRoutingModule ], }) export class RecipesModule { }the DropdownDirective is needed by both the app component and the feature module
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { DropdownDirective } from './dropdown.directive'; @NgModule({ declarations: [ DropdownDirective ], imports: [ CommonModule ], exports: [ CommonModule, DropdownDirective ] }) export class SharedModule { }in app.module remove the DropdownDirective import and declaration and import the shared module
... // import { DropdownDirective } from './shared/dropdown.directive'; import { SharedModule } from './shared/shared.module'; ... @NgModule({ declarations: [ ... // DropdownDirective, SignInComponent, SignUpComponent ], imports: [ ... SharedModule ], ... }) export class AppModule { }in recipes.module import the SharedModule
... import { SharedModule } from '../shared/shared.module'; @NgModule({ declarations: [ ... ], imports: [ ReactiveFormsModule, RecipesRoutingModule, SharedModule ], }) export class RecipesModule { }for selector have to declare it in the module where it is to be used
ng g c home --spec falsein AppRoutingModule change the empty path to the HomeComponent
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { ShoppingListComponent } from './shopping-list/shopping-list.component'; import { HomeComponent } from './home/home.component'; const appRoutes: Routes = [ { path: '', component: HomeComponent }, // loadChildren: < path to feature model >#< class name > { path: 'recipe', loadChildren: './recipes/recipes.module#RecipesModule' }, { path: 'shopping-list', component: ShoppingListComponent }, ]; @NgModule({ imports: [RouterModule.forRoot(appRoutes)], exports: [RouterModule] }) export class AppRoutingModule { }recipe module is now lazily loaded route protection on lazily loaded routes can be done using canActivate
{ path: 'recipes', loadChildren: './recipes/recipes.module#RecipesModule', canLoad: [AuthGuard] }AuthGuard needs to implement the CanLoad interface
import { ActivatedRouteSnapshot, CanActivate, CanLoad, Route, RouterStateSnapshot } from '@angular/router'; import { Injectable } from '@angular/core'; import { AuthService } from './auth.service'; import { Observable } from 'rxjs/Observable'; @Injectable() export class AuthGuard implements CanActivate, CanLoad { constructor(private authService: AuthService) { } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { return this.authService.isAuthenticated(); } canLoad(route: Route): Observable<boolean> | Promise<boolean> | boolean { return this.authService.isAuthenticated(); } }add the canLoad property to the JSON object in the app-routing module
... import { AuthGuard} from './auth/auth-guard.service'; const appRoutes: Routes = [ { path: '', component: HomeComponent }, { path: 'recipe', loadChildren: './recipes/recipes.module#RecipesModule', canLoad: [AuthGuard] }, { path: 'shopping-list', component: ShoppingListComponent }, ]; ... export class AppRoutingModule { }consider an app with an eagerly-loaded feature module and a lazily-loaded feature module
in the first case add a shared module which includes the log service in its providers
array
when the lazily-load module is loaded it gets a different instance of the service
because the child injector is used
don't provide services in shared modules especially if the services are to be used by lazily-loaded modules
core modules only imported by the root moduleng buildbuilds the app for JIT compiling
ng build --prodtries to optimize and minimize the code
ng build --prod --aotuses ahead of time compilation preload lazy loaded modules rather than wait for demand
... const appRoutes: Routes = [ ... ]; @NgModule({ imports: [RouterModule.forRoot(appRoutes, { preloadingStrategy: PreloadAllModules })], exports: [RouterModule] }) export class AppRoutingModule { }