完成上面的里程碑后,應(yīng)用程序很自然地長(zhǎng)大了。在某一個(gè)時(shí)間點(diǎn),你將達(dá)到一個(gè)頂點(diǎn),應(yīng)用將會(huì)需要過(guò)多的時(shí)間來(lái)加載。
為了解決這個(gè)問(wèn)題,請(qǐng)使用異步路由,它會(huì)根據(jù)請(qǐng)求來(lái)惰性加載某些特性模塊。惰性加載有很多好處。
你可以只在用戶請(qǐng)求時(shí)才加載某些特性區(qū)。
對(duì)于那些只訪問(wèn)應(yīng)用程序某些區(qū)域的用戶,這樣能加快加載速度。
你可以持續(xù)擴(kuò)充惰性加載特性區(qū)的功能,而不用增加初始加載的包體積。
你已經(jīng)完成了一部分。通過(guò)把應(yīng)用組織成一些模塊:AppModule
、HeroesModule
、AdminModule
和 CrisisCenterModule
, 你已經(jīng)有了可用于實(shí)現(xiàn)惰性加載的候選者。
有些模塊(比如 AppModule
)必須在啟動(dòng)時(shí)加載,但其它的都可以而且應(yīng)該惰性加載。 比如 AdminModule 就只有少數(shù)已認(rèn)證的用戶才需要它,所以你應(yīng)該只有在正確的人請(qǐng)求它時(shí)才加載。
把 "admin-routing.module.ts" 中的 admin
路徑從 'admin'
改為空路徑 ''
。
可以用空路徑路由來(lái)對(duì)路由進(jìn)行分組,而不用往 URL
中添加額外的路徑片段。 用戶仍舊訪問(wèn) "/admin",并且 AdminComponent
仍然作為用來(lái)包含子路由的路由組件。
打開(kāi) AppRoutingModule
,并把一個(gè)新的 admin
路由添加到它的 appRoutes
數(shù)組中。
給它一個(gè) loadChildren
屬性(替換掉 children
屬性)。 loadChildren
屬性接收一個(gè)函數(shù),該函數(shù)使用瀏覽器內(nèi)置的動(dòng)態(tài)導(dǎo)入語(yǔ)法 import('...')
來(lái)惰性加載代碼,并返回一個(gè)承諾(Promise
)。 其路徑是 AdminModule
的位置(相對(duì)于應(yīng)用的根目錄)。 當(dāng)代碼請(qǐng)求并加載完畢后,這個(gè) Promise
就會(huì)解析成一個(gè)包含 NgModule
的對(duì)象,也就是 AdminModule
。
Path:"app-routing.module.ts (load children)" 。
{
path: 'admin',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule),
},
注:
- 當(dāng)使用絕對(duì)路徑時(shí),
NgModule
的文件位置必須以 "src/app" 開(kāi)頭,以便正確解析。對(duì)于自定義的 使用絕對(duì)路徑的路徑映射表,你必須在項(xiàng)目的 "tsconfig.json" 中必須配置好baseUrl
和paths
屬性。
當(dāng)路由器導(dǎo)航到這個(gè)路由時(shí),它會(huì)用 loadChildren
字符串來(lái)動(dòng)態(tài)加載 AdminModule
,然后把 AdminModule
添加到當(dāng)前的路由配置中, 最后,它把所請(qǐng)求的路由加載到目標(biāo) admin
組件中。
惰性加載和重新配置工作只會(huì)發(fā)生一次,也就是在該路由首次被請(qǐng)求時(shí)。在后續(xù)的請(qǐng)求中,該模塊和路由都是立即可用的。
Angular 提供一個(gè)內(nèi)置模塊加載器,支持SystemJS 來(lái)異步加載模塊。如果你使用其它捆綁工具比如 Webpack,則使用 Webpack 的機(jī)制來(lái)異步加載模塊。
最后一步是把管理特性區(qū)從主應(yīng)用中完全分離開(kāi)。 根模塊 AppModule
既不能加載也不能引用 AdminModule
及其文件。
在 "app.module.ts" 中,從頂部移除 AdminModule
的導(dǎo)入語(yǔ)句,并且從 NgModule
的 imports
數(shù)組中移除 AdminModule
。
你已經(jīng)使用 CanActivate
保護(hù) AdminModule
了,它會(huì)阻止未授權(quán)用戶訪問(wèn)管理特性區(qū)。如果用戶未登錄,它就會(huì)跳轉(zhuǎn)到登錄頁(yè)。
但是路由器仍然會(huì)加載 AdminModule
—— 即使用戶無(wú)法訪問(wèn)它的任何一個(gè)組件。 理想的方式是,只有在用戶已登錄的情況下你才加載 AdminModule
。
添加一個(gè) CanLoad
守衛(wèi),它只在用戶已登錄并且嘗試訪問(wèn)管理特性區(qū)的時(shí)候,才加載 AdminModule
一次。
現(xiàn)有的 AuthGuard
的 checkLogin()
方法中已經(jīng)有了支持 CanLoad
守衛(wèi)的基礎(chǔ)邏輯。
打開(kāi) "auth.guard.ts",從 @angular/router
中導(dǎo)入 CanLoad
接口。 把它添加到 AuthGuard
類的 implements
列表中。 然后實(shí)現(xiàn) canLoad
,代碼如下:
Path:"src/app/auth/auth.guard.ts (CanLoad guard)" 。
canLoad(route: Route): boolean {
let url = `/${route.path}`;
return this.checkLogin(url);
}
路由器會(huì)把 canLoad()
方法的 route
參數(shù)設(shè)置為準(zhǔn)備訪問(wèn)的目標(biāo) URL。 如果用戶已經(jīng)登錄了,checkLogin()
方法就會(huì)重定向到那個(gè) URL
。
現(xiàn)在,把 AuthGuard
導(dǎo)入到 AppRoutingModule
中,并把 AuthGuard
添加到 admin
路由的 canLoad
數(shù)組中。 完整的 admin
路由是這樣的:
Path:"app-routing.module.ts (lazy admin route)" 。
{
path: 'admin',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule),
canLoad: [AuthGuard]
},
除了按需加載模塊外,還可以通過(guò)預(yù)加載方式異步加載模塊。
當(dāng)應(yīng)用啟動(dòng)時(shí),AppModule
被急性加載,這意味著它會(huì)立即加載。而 AdminModule
只在用戶點(diǎn)擊鏈接時(shí)加載,這叫做惰性加載。
預(yù)加載允許你在后臺(tái)加載模塊,以便當(dāng)用戶激活某個(gè)特定的路由時(shí),就可以渲染這些數(shù)據(jù)了。 考慮一下危機(jī)中心。 它不是用戶看到的第一個(gè)視圖。 默認(rèn)情況下,英雄列表才是第一個(gè)視圖。為了獲得最小的初始有效負(fù)載和最快的啟動(dòng)時(shí)間,你應(yīng)該急性加載 AppModule
和 HeroesModule
。
你可以惰性加載危機(jī)中心。 但是,你幾乎可以肯定用戶會(huì)在啟動(dòng)應(yīng)用之后的幾分鐘內(nèi)訪問(wèn)危機(jī)中心。 理想情況下,應(yīng)用啟動(dòng)時(shí)應(yīng)該只加載 AppModule
和 HeroesModule
,然后幾乎立即開(kāi)始后臺(tái)加載 CrisisCenterModule
。 在用戶瀏覽到危機(jī)中心之前,該模塊應(yīng)該已經(jīng)加載完畢,可供訪問(wèn)了。
在每次成功的導(dǎo)航后,路由器會(huì)在自己的配置中查找尚未加載并且可以預(yù)加載的模塊。 是否加載某個(gè)模塊,以及要加載哪些模塊,取決于預(yù)加載策略。
Router
提供了兩種預(yù)加載策略:
路由器或者完全不預(yù)加載或者預(yù)加載每個(gè)惰性加載模塊。 路由器還支持自定義預(yù)加載策略,以便完全控制要預(yù)加載哪些模塊以及何時(shí)加載。
本節(jié)將指導(dǎo)你把 CrisisCenterModule
改成惰性加載的,并使用 PreloadAllModules
策略來(lái)預(yù)加載所有惰性加載模塊。
修改路由配置,來(lái)惰性加載 CrisisCenterModule
。修改的步驟和配置惰性加載 AdminModule 時(shí)一樣。
CrisisCenterRoutingModule
中的路徑從 crisis-center
改為空字符串。AppRoutingModule
中添加一個(gè) crisis-center
路由。loadChildren
字符串來(lái)加載 CrisisCenterModule
。CrisisCenterModule
的引用。下面是打開(kāi)預(yù)加載之前的模塊修改版:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { Router } from '@angular/router';
import { AppComponent } from './app.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { ComposeMessageComponent } from './compose-message/compose-message.component';
import { AppRoutingModule } from './app-routing.module';
import { HeroesModule } from './heroes/heroes.module';
import { AuthModule } from './auth/auth.module';
@NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
HeroesModule,
AuthModule,
AppRoutingModule,
],
declarations: [
AppComponent,
ComposeMessageComponent,
PageNotFoundComponent
],
bootstrap: [ AppComponent ]
})
export class AppModule {
}
import { NgModule } from '@angular/core';
import {
RouterModule, Routes,
} from '@angular/router';
import { ComposeMessageComponent } from './compose-message/compose-message.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { AuthGuard } from './auth/auth.guard';
const appRoutes: Routes = [
{
path: 'compose',
component: ComposeMessageComponent,
outlet: 'popup'
},
{
path: 'admin',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule),
canLoad: [AuthGuard]
},
{
path: 'crisis-center',
loadChildren: () => import('./crisis-center/crisis-center.module').then(m => m.CrisisCenterModule)
},
{ path: '', redirectTo: '/heroes', pathMatch: 'full' },
{ path: '**', component: PageNotFoundComponent }
];
@NgModule({
imports: [
RouterModule.forRoot(
appRoutes,
)
],
exports: [
RouterModule
]
})
export class AppRoutingModule {}
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CrisisCenterHomeComponent } from './crisis-center-home/crisis-center-home.component';
import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { CrisisCenterComponent } from './crisis-center/crisis-center.component';
import { CrisisDetailComponent } from './crisis-detail/crisis-detail.component';
import { CanDeactivateGuard } from '../can-deactivate.guard';
import { CrisisDetailResolverService } from './crisis-detail-resolver.service';
const crisisCenterRoutes: Routes = [
{
path: '',
component: CrisisCenterComponent,
children: [
{
path: '',
component: CrisisListComponent,
children: [
{
path: ':id',
component: CrisisDetailComponent,
canDeactivate: [CanDeactivateGuard],
resolve: {
crisis: CrisisDetailResolverService
}
},
{
path: '',
component: CrisisCenterHomeComponent
}
]
}
]
}
];
@NgModule({
imports: [
RouterModule.forChild(crisisCenterRoutes)
],
exports: [
RouterModule
]
})
export class CrisisCenterRoutingModule { }
你可以現(xiàn)在嘗試它,并確認(rèn)在點(diǎn)擊了 “Crisis Center” 按鈕之后加載了 CrisisCenterModule
。
要為所有惰性加載模塊啟用預(yù)加載功能,請(qǐng)從 Angular 的路由模塊中導(dǎo)入 PreloadAllModules
。
RouterModule.forRoot()
方法的第二個(gè)參數(shù)接受一個(gè)附加配置選項(xiàng)對(duì)象。 preloadingStrategy
就是其中之一。 把 PreloadAllModules
添加到 forRoot()
調(diào)用中:
Path:"src/app/app-routing.module.ts (preload all)" 。
RouterModule.forRoot(
appRoutes,
{
enableTracing: true, // <-- debugging purposes only
preloadingStrategy: PreloadAllModules
}
)
這項(xiàng)配置會(huì)讓 Router
預(yù)加載器立即加載所有惰性加載路由(帶 loadChildren
屬性的路由)。
當(dāng)訪問(wèn) "http://localhost:4200 時(shí),/heroes" 路由立即隨之啟動(dòng),并且路由器在加載了 HeroesModule
之后立即開(kāi)始加載 CrisisCenterModule
。
目前,AdminModule
并沒(méi)有預(yù)加載,因?yàn)?CanLoad
阻塞了它。
CanLoad 會(huì)阻塞預(yù)加載
PreloadAllModules
策略不會(huì)加載被CanLoad
守衛(wèi)所保護(hù)的特性區(qū)。
幾步之前,你剛剛給 AdminModule
中的路由添加了 CanLoad
守衛(wèi),以阻塞加載那個(gè)模塊,直到用戶認(rèn)證結(jié)束。 CanLoad
守衛(wèi)的優(yōu)先級(jí)高于預(yù)加載策略。
如果你要加載一個(gè)模塊并且保護(hù)它防止未授權(quán)訪問(wèn),請(qǐng)移除 CanLoad
守衛(wèi),只單獨(dú)依賴CanActivate
守衛(wèi)。
在很多場(chǎng)景下,預(yù)加載的每個(gè)惰性加載模塊都能正常工作。但是,考慮到低帶寬和用戶指標(biāo)等因素,可以為特定的特性模塊使用自定義預(yù)加載策略。
本節(jié)將指導(dǎo)你添加一個(gè)自定義策略,它只預(yù)加載 data.preload
標(biāo)志為 true
路由?;叵胍幌拢憧梢栽诼酚傻?data
屬性中添加任何東西。
在 AppRoutingModule
的 crisis-center
路由中設(shè)置 data.preload
標(biāo)志。
Path:"src/app/app-routing.module.ts (route data preload)" 。
{
path: 'crisis-center',
loadChildren: () => import('./crisis-center/crisis-center.module').then(m => m.CrisisCenterModule),
data: { preload: true }
},
生成一個(gè)新的 SelectivePreloadingStrategy
服務(wù)。
ng generate service selective-preloading-strategy
使用下列內(nèi)容替換 "selective-preloading-strategy.service.ts":
Path:"src/app/selective-preloading-strategy.service.ts" 。
import { Injectable } from '@angular/core';
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable, of } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class SelectivePreloadingStrategyService implements PreloadingStrategy {
preloadedModules: string[] = [];
preload(route: Route, load: () => Observable<any>): Observable<any> {
if (route.data && route.data['preload']) {
// add the route path to the preloaded module array
this.preloadedModules.push(route.path);
// log the route path to the console
console.log('Preloaded: ' + route.path);
return load();
} else {
return of(null);
}
}
}
SelectivePreloadingStrategyService
實(shí)現(xiàn)了 PreloadingStrategy
,它有一個(gè)方法 preload()
。
路由器會(huì)用兩個(gè)參數(shù)來(lái)調(diào)用 preload()
方法:
loader
)函數(shù),它能異步加載帶路由的模塊。
preload
的實(shí)現(xiàn)要返回一個(gè) Observable
。 如果該路由應(yīng)該預(yù)加載,它就會(huì)返回調(diào)用加載器函數(shù)所返回的 Observable
。 如果該路由不應(yīng)該預(yù)加載,它就返回一個(gè) null
值的 Observable
對(duì)象。
在這個(gè)例子中,如果路由的 data.preload
標(biāo)志是真值,則 preload()
方法會(huì)加載該路由。
它的副作用是 SelectivePreloadingStrategyService
會(huì)把所選路由的 path
記錄在它的公共數(shù)組 preloadedModules
中。
很快,你就會(huì)擴(kuò)展 AdminDashboardComponent
來(lái)注入該服務(wù),并且顯示它的 preloadedModules
數(shù)組。
但是首先,要對(duì) AppRoutingModule
做少量修改。
SelectivePreloadingStrategyService
導(dǎo)入到 AppRoutingModule
中。PreloadAllModules
策略替換成對(duì) forRoot()
的調(diào)用,并且傳入這個(gè) SelectivePreloadingStrategyService
。SelectivePreloadingStrategyService
策略添加到 AppRoutingModule
的 providers
數(shù)組中,以便它可以注入到應(yīng)用中的任何地方。
現(xiàn)在,編輯 AdminDashboardComponent
以顯示這些預(yù)加載路由的日志。
導(dǎo)入 SelectivePreloadingStrategyService
(它是一個(gè)服務(wù))。
把它注入到儀表盤(pán)的構(gòu)造函數(shù)中。
修改模板來(lái)顯示這個(gè)策略服務(wù)的 preloadedModules
數(shù)組。
現(xiàn)在文件如下:
Path:"src/app/admin/admin-dashboard/admin-dashboard.component.ts (preloaded modules)" 。
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { SelectivePreloadingStrategyService } from '../../selective-preloading-strategy.service';
@Component({
selector: 'app-admin-dashboard',
templateUrl: './admin-dashboard.component.html',
styleUrls: ['./admin-dashboard.component.css']
})
export class AdminDashboardComponent implements OnInit {
sessionId: Observable<string>;
token: Observable<string>;
modules: string[];
constructor(
private route: ActivatedRoute,
preloadStrategy: SelectivePreloadingStrategyService
) {
this.modules = preloadStrategy.preloadedModules;
}
ngOnInit() {
// Capture the session ID if available
this.sessionId = this.route
.queryParamMap
.pipe(map(params => params.get('session_id') || 'None'));
// Capture the fragment if available
this.token = this.route
.fragment
.pipe(map(fragment => fragment || 'None'));
}
}
一旦應(yīng)用加載完了初始路由,CrisisCenterModule
也被預(yù)加載了。 通過(guò) Admin
特性區(qū)中的記錄就可以驗(yàn)證它,“Preloaded Modules”中列出了 crisis-center
。 它也被記錄到了瀏覽器的控制臺(tái)。
你已經(jīng)設(shè)置好了路由,并且用命令式和聲明式的方式導(dǎo)航到了很多不同的路由。但是,任何應(yīng)用的需求都會(huì)隨著時(shí)間而改變。 你把鏈接 "/heroes" 和 "hero/:id" 指向了 HeroListComponent
和 HeroDetailComponent
組件。 如果有這樣一個(gè)需求,要把鏈接 "heroes" 變成 "superheroes",你可能仍然希望以前的 URL
能正常導(dǎo)航。 但你也不想在應(yīng)用中找到并修改每一個(gè)鏈接,這時(shí)候,重定向就可以省去這些瑣碎的重構(gòu)工作。
把 /heroes 改為 /superheroes
本節(jié)將指導(dǎo)你將 Hero
路由遷移到新的 URL。在導(dǎo)航之前,Router
會(huì)檢查路由配置中的重定向語(yǔ)句,以便將來(lái)按需觸發(fā)重定向。要支持這種修改,你就要在 "heroes-routing.module" 文件中把老的路由重定向到新的路由。
Path:"src/app/heroes/heroes-routing.module.ts (heroes redirects)" 。
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HeroListComponent } from './hero-list/hero-list.component';
import { HeroDetailComponent } from './hero-detail/hero-detail.component';
const heroesRoutes: Routes = [
{ path: 'heroes', redirectTo: '/superheroes' },
{ path: 'hero/:id', redirectTo: '/superhero/:id' },
{ path: 'superheroes', component: HeroListComponent, data: { animation: 'heroes' } },
{ path: 'superhero/:id', component: HeroDetailComponent, data: { animation: 'hero' } }
];
@NgModule({
imports: [
RouterModule.forChild(heroesRoutes)
],
exports: [
RouterModule
]
})
export class HeroesRoutingModule { }
注意,這里有兩種類型的重定向。第一種是不帶參數(shù)的從 "/heroes" 重定向到 "/superheroes"。這是一種非常直觀的重定向。第二種是從 "/hero/:id" 重定向到 "/superhero/:id",它還要包含一個(gè) :id
路由參數(shù)。 路由器重定向時(shí)使用強(qiáng)大的模式匹配功能,這樣,路由器就會(huì)檢查 URL
,并且把 path
中帶的路由參數(shù)替換成相應(yīng)的目標(biāo)形式。以前,你導(dǎo)航到形如 "/hero/15" 的 URL
時(shí),帶了一個(gè)路由參數(shù) id
,它的值是 15。
在重定向的時(shí)候,路由器還支持查詢參數(shù)和片段(
fragment
)。
- 當(dāng)使用絕對(duì)地址重定向時(shí),路由器將會(huì)使用路由配置的 `redirectTo` 屬性中規(guī)定的查詢參數(shù)和片段。
- 當(dāng)使用相對(duì)地址重定向時(shí),路由器將會(huì)使用源地址(跳轉(zhuǎn)前的地址)中的查詢參數(shù)和片段。
目前,空路徑被重定向到了 "/heroes",它又被重定向到了 "/superheroes"。這樣不行,因?yàn)?Router
在每一層的路由配置中只會(huì)處理一次重定向。這樣可以防止出現(xiàn)無(wú)限循環(huán)的重定向。
所以,你要在 "app-routing.module.ts" 中修改空路徑路由,讓它重定向到 "/superheroes"。
Path:"src/app/app-routing.module.ts (superheroes redirect)" 。
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ComposeMessageComponent } from './compose-message/compose-message.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { AuthGuard } from './auth/auth.guard';
import { SelectivePreloadingStrategyService } from './selective-preloading-strategy.service';
const appRoutes: Routes = [
{
path: 'compose',
component: ComposeMessageComponent,
outlet: 'popup'
},
{
path: 'admin',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule),
canLoad: [AuthGuard]
},
{
path: 'crisis-center',
loadChildren: () => import('./crisis-center/crisis-center.module').then(m => m.CrisisCenterModule),
data: { preload: true }
},
{ path: '', redirectTo: '/superheroes', pathMatch: 'full' },
{ path: '**', component: PageNotFoundComponent }
];
@NgModule({
imports: [
RouterModule.forRoot(
appRoutes,
{
enableTracing: false, // <-- debugging purposes only
preloadingStrategy: SelectivePreloadingStrategyService,
}
)
],
exports: [
RouterModule
]
})
export class AppRoutingModule { }
由于 routerLink
與路由配置無(wú)關(guān),所以你要修改相關(guān)的路由鏈接,以便在新的路由激活時(shí),它們也能保持激活狀態(tài)。還要修改 "app.component.ts" 模板中的 "/heroes" 這個(gè) routerLink
。
Path:"src/app/app.component.html (superheroes active routerLink))" 。
<h1 class="title">Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/superheroes" routerLinkActive="active">Heroes</a>
<a routerLink="/admin" routerLinkActive="active">Admin</a>
<a routerLink="/login" routerLinkActive="active">Login</a>
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
</nav>
<div [@routeAnimation]="getAnimationData(routerOutlet)">
<router-outlet #routerOutlet="outlet"></router-outlet>
</div>
<router-outlet name="popup"></router-outlet>
修改 "hero-detail.component.ts" 中的 goToHeroes()
方法,使用可選的路由參數(shù)導(dǎo)航回 "/superheroes"。
Path:"src/app/heroes/hero-detail/hero-detail.component.ts (goToHeroes)" 。
gotoHeroes(hero: Hero) {
let heroId = hero ? hero.id : null;
// Pass along the hero id if available
// so that the HeroList component can select that hero.
// Include a junk 'foo' property for fun.
this.router.navigate(['/superheroes', { id: heroId, foo: 'foo' }]);
}
當(dāng)這些重定向設(shè)置好之后,所有以前的路由都指向了它們的新目標(biāo),并且每個(gè) URL
也仍然能正常工作。
要確定你的路由是否真的按照正確的順序執(zhí)行的,你可以審查路由器的配置。
可以通過(guò)注入路由器并在控制臺(tái)中記錄其 config
屬性來(lái)實(shí)現(xiàn)。 例如,把 AppModule
修改為這樣,并在瀏覽器的控制臺(tái)窗口中查看最終的路由配置。
Path:"src/app/app.module.ts (inspect the router config)" 。
export class AppModule {
// Diagnostic only: inspect router configuration
constructor(router: Router) {
// Use a custom replacer to display function names in the route configs
const replacer = (key, value) => (typeof value === 'function') ? value.name : value;
console.log('Routes: ', JSON.stringify(router.config, replacer, 2));
}
}
對(duì)這個(gè)已完成的路由器應(yīng)用,參見(jiàn) 下載范例 的最終代碼。
更多建議: