新聞中心
常見路由任務
本主題講述當把 Angular 路由器添加到應用中時,如何實現(xiàn)多種常見路由任務。

成都創(chuàng)新互聯(lián)是專業(yè)的富源網(wǎng)站建設公司,富源接單;提供成都網(wǎng)站建設、成都做網(wǎng)站,網(wǎng)頁設計,網(wǎng)站設計,建網(wǎng)站,PHP網(wǎng)站建設等專業(yè)做網(wǎng)站服務;采用PHP框架,可快速的進行富源網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!
生成一個支持路由的應用
下面的命令會用 Angular CLI 來生成一個帶有應用路由模塊(?AppRoutingModule?)的基本 Angular 應用,它是一個 NgModule,可用來配置路由。下面的例子中應用的名字是 ?routing-app?。
ng new routing-app --routing --defaults為路由添加組件
為了使用 Angular 的路由器,應用至少要有兩個組件才能從一個導航到另一個。要使用 CLI 創(chuàng)建組件,請在命令行輸入以下內容,其中 ?first ?是組件的名稱:
ng generate component first為第二個組件重復這個步驟,但給它一個不同的名字。這里的新名字是 ?second?。
ng generate component secondCLI 會自動添加 ?Component ?后綴,所以如果在編寫 ?first-component?,那么其組件名就是 ?FirstComponentComponent?。
本指南適用于 CLI 生成的 Angular 應用。如果你是手動工作的,請確保你的 index.html 文件的 ?
? 中有 ?
? 語句。這里假定 ?
app?文件夾是應用的根目錄,并使用 ?
"/"? 作為基礎路徑。
導入這些新組件
要使用這些新組件,請把它們導入到該文件頂部的 ?AppRoutingModule ?中,具體如下:
import { FirstComponent } from './first/first.component';
import { SecondComponent } from './second/second.component';定義一個基本路由
創(chuàng)建路由有三個基本的構建塊。
把 ?AppRoutingModule ?導入 ?AppModule ?并把它添加到 ?imports ?數(shù)組中。
Angular CLI 會為你執(zhí)行這一步驟。但是,如果要手動創(chuàng)建應用或使用現(xiàn)存的非 CLI 應用,請驗證導入和配置是否正確。下面是使用 ?--routing? 標志生成的默認 ?AppModule?。
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module'; // CLI imports AppRoutingModule
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule // CLI adds AppRoutingModule to the AppModule's imports array
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }- 把 ?
RouterModule?和 ?Routes?導入到你的路由模塊中。 - 在 ?
Routes?數(shù)組中定義你的路由。 - 把這些路由添加到你的應用中。
Angular CLI 會自動執(zhí)行這一步驟。CLI 還為你的路由設置了 ?Routes ?數(shù)組,并為 ?@NgModule()? 配置了 ?imports ?和 ?exports ?數(shù)組。
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router'; // CLI imports router
const routes: Routes = []; // sets up routes constant where you define your routes
// configures NgModule imports and exports
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }這個數(shù)組中的每個路由都是一個包含兩個屬性的 JavaScript 對象。第一個屬性 ?path ?定義了該路由的 URL 路徑。第二個屬性 ?component ?定義了要讓 Angular 用作相應路徑的組件。
const routes: Routes = [
{ path: 'first-component', component: FirstComponent },
{ path: 'second-component', component: SecondComponent },
];現(xiàn)在你已經(jīng)定義了路由,可以把它們添加到應用中了。首先,添加到這兩個組件的鏈接。把要添加路由的鏈接賦值給 ?routerLink ?屬性。將屬性的值設置為該組件,以便在用戶點擊各個鏈接時顯示這個值。接下來,修改組件模板以包含 ?? 標簽。該元素會通知 Angular,你可以用所選路由的組件更新應用的視圖。
Angular Router App
路由順序
路由的順序很重要,因為 ?Router ?在匹配路由時使用“先到先得”策略,所以應該在不那么具體的路由前面放置更具體的路由。首先列出靜態(tài)路徑的路由,然后是一個與默認路由匹配的空路徑路由。通配符路由是最后一個,因為它匹配每一個 URL,只有當其它路由都沒有匹配時,?Router ?才會選擇它。
獲取路由信息
通常,當用戶導航你的應用時,你會希望把信息從一個組件傳遞到另一個組件。例如,考慮一個顯示雜貨商品購物清單的應用。列表中的每一項都有一個唯一的 ?id?。要想編輯某個項目,用戶需要單擊“編輯”按鈕,打開一個 ?EditGroceryItem ?組件。你希望該組件得到該商品的 ?id?,以便它能向用戶顯示正確的信息。
可以用一個路由把這種類型的信息傳給你的應用組件。要做到這一點,你可以使用 ?ActivatedRoute ?接口。
要從路由中獲取信息:
- 把 ?
ActivatedRoute?和 ?ParamMap?導入你的組件。 - 通過把 ?
ActivatedRoute?的一個實例添加到你的應用的構造函數(shù)中來注入它: - 更新 ?
ngOnInit()? 方法來訪問這個 ?ActivatedRoute?并跟蹤 ?name?參數(shù):
import { Router, ActivatedRoute, ParamMap } from '@angular/router';這些 import 語句添加了組件所需的幾個重要元素。
constructor(
private route: ActivatedRoute,
) {}ngOnInit() {
this.route.queryParams.subscribe(params => {
this.name = params['name'];
});
}注意:前面的例子使用了一個變量 ?name?,并根據(jù) ?name ?參數(shù)給它賦值。
設置通配符路由
當用戶試圖導航到那些不存在的應用部件時,在正常的應用中應該能得到很好的處理。要在應用中添加此功能,需要設置通配符路由。當所請求的 URL 與任何路由器路徑都不匹配時,Angular 路由器就會選擇這個路由。
要設置通配符路由,請在 ?routes ?定義中添加以下代碼。
{ path: '**', component: }
這兩個星號 ?**? 告訴 Angular,這個 ?routes ?定義是通配符路由。對于 component 屬性,你可以使用應用中的任何組件。常見的選擇包括應用專屬的 ?PageNotFoundComponent?,你可以定義它來向用戶展示 404 頁面,或者跳轉到應用的主組件。通配符路由是最后一個路由,因為它匹配所有的 URL。
顯示 404 頁面
要顯示 404 頁面,請設置一個通配符路由,并將 ?component ?屬性設置為你要用于 404 頁面的組件,如下所示:
const routes: Routes = [
{ path: 'first-component', component: FirstComponent },
{ path: 'second-component', component: SecondComponent },
{ path: '**', component: PageNotFoundComponent }, // Wildcard route for a 404 page
];?path ?為 ?**? 的最后一條路由是通配符路由。如果請求的 URL 與前面列出的路徑不匹配,路由器會選擇這個路由,并把該用戶送到 ?PageNotFoundComponent?。
設置重定向
要設置重定向,請使用重定向源的 ?path?、要重定向目標的 ?component ?和一個 ?pathMatch ?值來配置路由,以告訴路由器該如何匹配 URL。
const routes: Routes = [
{ path: 'first-component', component: FirstComponent },
{ path: 'second-component', component: SecondComponent },
{ path: '', redirectTo: '/first-component', pathMatch: 'full' }, // redirect to `first-component`
{ path: '**', component: PageNotFoundComponent }, // Wildcard route for a 404 page
];在這個例子中,第三個路由是重定向路由,所以路由器會默認跳到 ?first-component? 路由。注意,這個重定向路由位于通配符路由之前。這里的 ?path: ''? 表示使用初始的相對 URL( ?''? )。
嵌套路由
隨著你的應用變得越來越復雜,你可能要創(chuàng)建一些根組件之外的相對路由。這些嵌套路由類型稱為子路由。這意味著你要為你的應用添加第二 ??,因為它是 ?AppComponent ?之外的另一個 ??。
在這個例子中,還有兩個子組件,?child-a? 和 ?child-b?。這里的 ?FirstComponent ?有它自己的 ?? 和 ?AppComponent ?之外的第二 ??。
First Component
子路由和其它路由一樣,同時需要 ?path ?和 ?component?。唯一的區(qū)別是你要把子路由放在父路由的 ?children ?數(shù)組中。
const routes: Routes = [
{
path: 'first-component',
component: FirstComponent, // this is the component with the in the template
children: [
{
path: 'child-a', // child route path
component: ChildAComponent, // child route component that the router renders
},
{
path: 'child-b',
component: ChildBComponent, // another child route component that the router renders
},
],
},
]; 使用相對路徑
相對路徑允許你定義相對于當前 URL 段的路徑。下面的例子展示了到另一個組件 ?second-component? 的相對路由。?FirstComponent ?和 ?SecondComponent ?在樹中處于同一級別,但是,指向 ?SecondComponent ?的鏈接位于 ?FirstComponent ?中,這意味著路由器必須先上升一個級別,然后進入二級目錄才能找到 ?SecondComponent???梢杂?nbsp;?../? 符號來上升一個級別,而不用寫出到 ?SecondComponent ?的完整路徑。
First Component
除了 ?../?,還可以使用 ?./? 或者不帶前導斜杠來指定當前級別。
指定相對路由
要指定相對路由,請使用 ?NavigationExtras ?中的 ?relativeTo? 屬性。在組件類中,從 ?@angular/router? 導入 ?NavigationExtras?。
然后在導航方法中使用 ?relativeTo? 參數(shù)。在鏈接參數(shù)數(shù)組(它包含 ?items?)之后添加一個對象,把該對象的 ?relativeTo ?屬性設置為當前的 ?ActivatedRoute?,也就是 ?this.route?。
goToItems() {
this.router.navigate(['items'], { relativeTo: this.route });
}?goToItems()? 方法會把目標 URI 解釋為相對于當前路由的,并導航到 ?items ?路由。
訪問查詢參數(shù)和片段
有時,應用中的某個特性需要訪問路由的部件,比如查詢參數(shù)或片段(fragment)。本教程的這個階段使用了一個“英雄之旅”中的列表視圖,你可以在其中點擊一個英雄來查看詳情。路由器使用 ?id ?來顯示正確的英雄的詳情。
首先,在要導航的組件中導入以下成員。
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';接下來,注入當前路由(ActivatedRoute)服務:
constructor(private route: ActivatedRoute) {}配置這個類,讓你有一個可觀察對象 ?heroes$?、一個用來保存英雄的 ?id ?號的 ?selectedId?,以及 ?ngOnInit()? 中的英雄們,添加下面的代碼來獲取所選英雄的 ?id?。這個代碼片段假設你有一個英雄列表、一個英雄服務、一個能獲取你的英雄的函數(shù),以及用來渲染你的列表和細節(jié)的 HTML,就像在《英雄之旅》例子中一樣。
heroes$: Observable;
selectedId: number;
heroes = HEROES;
ngOnInit() {
this.heroes$ = this.route.paramMap.pipe(
switchMap(params => {
this.selectedId = Number(params.get('id'));
return this.service.getHeroes();
})
);
}
接下來,在要導航到的組件中,導入以下成員。
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
import { Observable } from 'rxjs';在組件類的構造函數(shù)中注入 ?ActivatedRoute ?和 ?Router?,這樣在這個組件中就可以用它們了:
hero$: Observable;
constructor(
private route: ActivatedRoute,
private router: Router ) {}
ngOnInit() {
const heroId = this.route.snapshot.paramMap.get('id');
this.hero$ = this.service.getHero(heroId);
}
gotoItems(hero: Hero) {
const heroId = hero ? hero.id : null;
// Pass along the hero id if available
// so that the HeroList component can select that item.
this.router.navigate(['/heroes', { id: heroId }]);
}
惰性加載
你可以配置路由定義來實現(xiàn)惰性加載模塊,這意味著 Angular 只會在需要時才加載這些模塊,而不是在應用啟動時就加載全部。 另外,你可以在后臺預加載一些應用部件來改善用戶體驗。
防止未經(jīng)授權的訪問
使用路由守衛(wèi)來防止用戶未經(jīng)授權就導航到應用的某些部分。Angular 中提供了以下路由守衛(wèi):
- ?
CanActivate? - ?
CanActivateChild? - ?
CanDeactivate? - ?
Resolve? - ?
CanLoad?
要想使用路由守衛(wèi),可以考慮使用無組件路由,因為這對于保護子路由很方便。
為你的守衛(wèi)創(chuàng)建一項服務:
ng generate guard your-guard請在守衛(wèi)類里實現(xiàn)你要用到的守衛(wèi)。下面的例子使用 ?CanActivate ?來保護該路由。
export class YourGuard implements CanActivate {
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): boolean {
// your logic goes here
}
}在路由模塊中,在 ?routes ?配置中使用相應的屬性。這里的 ?canActivate ?會告訴路由器它要協(xié)調到這個特定路由的導航。
{
path: '/your-path',
component: YourComponent,
canActivate: [YourGuard],
}鏈接參數(shù)數(shù)組
鏈接參數(shù)數(shù)組保存路由導航時所需的成分:
- 指向目標組件的那個路由的路徑(path)
- 必備路由參數(shù)和可選路由參數(shù),它們將進入該路由的 URL
可以把 ?RouterLink ?指令綁定到一個數(shù)組,就像這樣:
Heroes在指定路由參數(shù)時,使用如下的兩元素數(shù)組:
{{ hero.id }}{{ hero.name }}
可以在對象中提供可選的路由參數(shù),比如 ?{ foo: 'foo' }? :
Crisis Center這三個例子涵蓋了你在單級路由的應用中所需的一切。不過,在你添加一個像危機中心一樣的子路由時,你可以創(chuàng)建新鏈接數(shù)組。
下面這個最小化 ?RouterLink ?例子是基于危機中心指定的默認子路由構建的。
Crisis Center請注意以下事項:
- 數(shù)組中的第一個條目標記出了父路由(?
/crisis-center?)。 - 這個父路由沒有參數(shù)。
- 沒有默認的子路由,因此你得選取一個。
- 你決定跳轉到 ?
CrisisListComponent?,它的路由路徑是'/',但你不用顯式的添加它。
考慮以下路由器鏈接,它將從應用的根目錄導航到巨龍危機(Dragon Crisis):
Dragon Crisis- 數(shù)組中的第一個條目標記出了父路由(?
/crisis-center?)。 - 這個父路由沒有參數(shù)。
- 數(shù)組中的第二個條目('/:id')用來標記出到指定危機的詳情頁的子路由。
- 詳細的子路由需要一個 ?
id?路由參數(shù)。 - 你把巨龍危機的 ?
id?添加為該數(shù)組中的第二個條目(1)。 - 最終生成的路徑是 ?
/crisis-center/1?。
你也可以把危機中心的路由單獨重新定義為 ?AppComponent ?的模板:
template: `
Angular Router
`總之,你可以用一級、兩級或多級路由來寫應用程序。 鏈接參數(shù)數(shù)組提供了用來表示任意深度路由的鏈接參數(shù)數(shù)組以及任意合法的路由參數(shù)序列、必須的路由器參數(shù)以及可選的路由參數(shù)對象。
LocationStrategy 和瀏覽器的網(wǎng)址樣式
當路由器導航到一個新的組件視圖時,它會用該視圖的 URL 來更新瀏覽器的當前地址以及歷史。
現(xiàn)代 HTML 5 瀏覽器支持history.pushState API, 這是一項可以改變?yōu)g覽器的當前地址和歷史,卻又不會觸發(fā)服務端頁面請求的技術。 路由器可以合成出一個“自然的”URL,它看起來和那些需要進行頁面加載的 URL 沒什么區(qū)別。
下面是危機中心的 URL 在“HTML 5 pushState”風格下的樣子:
localhost:3002/crisis-center/老舊的瀏覽器在當前地址的 URL 變化時總會往服務器發(fā)送頁面請求……唯一的例外規(guī)則是:當這些變化位于“#”(被稱為“hash”)后面時不會發(fā)送。通過把應用內的路由 URL 拼接在 ?#? 之后,路由器可以獲得這條“例外規(guī)則”帶來的優(yōu)點。下面是到危機中心路由的“hash URL”:
localhost:3002/src/#/crisis-center/路由器通過兩種 ?LocationStrategy ?提供者來支持所有這些風格:
- ?
PathLocationStrategy?- 默認的策略,支持“HTML 5 pushState”風格。 - ?
HashLocationStrategy?- 支持“hash URL”風格。
?RouterModule.forRoot()? 函數(shù)把 ?LocationStrategy ?設置成了 ?PathLocationStrategy?,使其成為了默認策略。 你還可以在啟動過程中改寫(override)它,來切換到 ?HashLocationStrategy ?風格。
選擇路由策略
你必須在開發(fā)項目的早期就選擇一種路由策略,因為一旦該應用進入了生產(chǎn)階段,你網(wǎng)站的訪問者就會使用并依賴應用的這些 URL 引用。
幾乎所有的 Angular 項目都會使用默認的 HTML 5 風格。它生成的 URL 更易于被用戶理解,它也為將來做服務端渲染預留了空間。
在服務器端渲染指定的頁面,是一項可以在該應用首次加載時大幅提升響應速度的技術。那些原本需要十秒甚至更長時間加載的應用,可以預先在服務端渲染好,并在少于一秒的時間內完整渲染在用戶的設備上。
只有當應用的 URL 看起來像是標準的 Web URL,中間沒有 hash(#)時,這個選項才能生效。
路由器使用瀏覽器的 history.pushState API 進行導航。借助 ?pushState ?你自定義應用中的 URL 路徑 ?localhost:4200/crisis-center?,應用內的 URL 和服務器的 URL 沒有區(qū)別。
現(xiàn)代的 HTML5 瀏覽器都支持 ?pushState?,這也就是為什么很多人把這種 URL 形式稱為 "HTML 5" 風格的 URL。
你必須在應用的 ?index.html? 中添加一個 pushState ?路由正常工作。 瀏覽器要用 ?? 的值為引用 CSS、腳本和圖片文件時使用的相對 URL 添加前綴。
請把 ?? 元素添加在 ?? 標簽的緊后面。如果應用的根目錄是 ?app ?目錄,那么就可以像這個應用程序一樣,設置 ?index.html? 中的 ?href ?值。代碼如下。
HTML5 網(wǎng)址和
后面的指南中會引用 URL 的不同部分。下圖是這些部分所指內容的梗概:
foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment由于路由器默認使用 “HTML 5 pushState” 風格,所以你必須用一個 ?? 來配置該策略(Strategy)。
配置該策略的首選方式是往 ?index.html? 的 ?? 中添加一個
如果沒有該標記,瀏覽器就可能無法在“深度鏈接”進入應用時加載資源(圖片,CSS,腳本)。
有些開發(fā)人員可能無法添加 ?? 元素,這可能是因為它們沒有訪問 ?? 或 ?index.html? 的權限。
它們仍然可以使用 HTML 5 格式的 URL,但要采取如下步驟進行補救:
- 用適當?shù)腫APP_BASE_HREF][]值提供(provide)路由器。
- 對所有 Web 資源(CSS、圖片、腳本和模板 HTML 文件)使用根 URL(高優(yōu)先度 URL)。
- ?
? 的 ?path?應該用 "/" 結尾,瀏覽器會忽略 ?path?中最右邊的 "/" 后面的字符。 - 如果 ?
? 包含 ?query?部分,則只有頁內鏈接的 ?path?部分為空并且沒有 ?query?時,才會使用這里的 ?query?。 這意味著 ?? 中的 ?query?部分只有在使用 ?HashLocationStrategy?策略時才有用。 - 如果頁內鏈接是根 URL(高優(yōu)先度 URL),則 ?
? 不會使用。在這種方式下,?APP_BASE_HREF?的優(yōu)先度將會導致所有由 Angular 創(chuàng)建的鏈接忽略 ??。 - ?
? 中的片段(#后面的部分)永遠不會被使用。
對所有 Web 資源使用絕對地址:CSS、圖片、腳本、模板 HTML。
HashLocationStrategy
可以在根模塊的 ?RouterModule.forRoot()? 的第二個參數(shù)中傳入一個帶有 ?useHash: true? 的對象,以回到基于 ?HashLocationStrategy ?的傳統(tǒng)方式。
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
const routes: Routes = [
];
@NgModule({
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot(routes, { useHash: true }) // .../#/crisis-center/
],
declarations: [
AppComponent,
PageNotFoundComponent
],
providers: [
],
bootstrap: [ AppComponent ]
})
export class AppModule { } 標題名稱:創(chuàng)新互聯(lián)Angular教程:Angular 常見路由任務
分享路徑:http://m.5511xx.com/article/cocdsid.html


咨詢
建站咨詢
