您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關Angular 4.x路由的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
Installing the router
首先第一件事,我們需要安裝 Angular Router。你可以通過運行以下任一操作來執行此操作:
yarn add @angular/router # OR npm i --save @angular/router
以上命令執行后,將會自動下載 @angular/router
模塊到 node_modules
文件夾中。
Base href
我們需要做的最后一件事,是將 <base>
標簽添加到我們的 index.html
文件中。路由需要根據這個來確定應用程序的根目錄。例如,當我們轉到 http://example.com/page1
時,如果我們沒有定義應用程序的基礎路徑,路由將無法知道我們的應用的托管地址是 http://example.com
還是 http://example.com/page1
。
這件事操作起來很簡單,只需打開項目中的 index.html 文件,添加相應的 <base> 標簽,具體如下:
<!doctype html> <html> <head> <base href="/" rel="external nofollow" > <title>Application</title> </head> <body> <app-root></app-root> </body> </html>
以上配置信息告訴 Angular 路由,應用程序的根目錄是 /
。
Using the router
要使用路由,我們需要在 AppModule
模塊中,導入 RouterModule
。具體如下:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { RouterModule } from '@angular/router'; import { AppComponent } from './app.component'; @NgModule({ imports: [ BrowserModule, RouterModule ], bootstrap: [ AppComponent ], declarations: [ AppComponent ] }) export class AppModule {}
此時我們的路由還不能正常工作,因為我們還未配置應用程序路由的相關信息。RouterModule
對象為我們提供了兩個靜態的方法:forRoot()
和 forChild()
來配置路由信息。
RouterModule.forRoot()
RouterModule.forRoot() 方法用于在主模塊中定義主要的路由信息,通過調用該方法使得我們的主模塊可以訪問路由模塊中定義的所有指令。接下來我們來看一下如何使用 forRoot()
:
// ... import { Routes, RouterModule } from '@angular/router'; export const ROUTES: Routes = []; @NgModule({ imports: [ BrowserModule, RouterModule.forRoot(ROUTES) ], // ... }) export class AppModule {}
我們通過使用 const
定義路由的配置信息,然后把它作為參數調用 RouterModule.forRoot()
方法,而不是直接使用 RouterModule.forRoot([...])
這種方式,這樣做的好處是方便我們在需要的時候導出 ROUTES
到其它模塊中。
RouterModule.forChild()
RouterModule.forChild() 與 Router.forRoot() 方法類似,但它只能應用在特性模塊中。
友情提示:根模塊中使用 forRoot(),子模塊中使用 forChild()
這個功能非常強大,因為我們不必在一個地方(我們的主模塊)定義所有路由信息。反之,我們可以在特性模塊中定義模塊特有的路由信息,并在必要的時候將它們導入我們主模塊。RouterModule.forChild()
的使用方法如下:
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Routes, RouterModule } from '@angular/router'; export const ROUTES: Routes = []; @NgModule({ imports: [ CommonModule, RouterModule.forChild(ROUTES) ], // ... }) export class ChildModule {}
通過以上示例,我們知道在主模塊和特性模塊中,路由配置對象的類型是一樣的,區別只是主模塊和特性模塊中需調用不同的方法,來配置模塊路由。接下來我們來介紹一下如何配置 ROUTES
對象。
Configuring a route
我們定義的所有路由都是作為 ROUTES
數組中的對象。首先,為我們的主頁定義一個路由:
import { Routes, RouterModule } from '@angular/router'; import { HomeComponent } from './home/home.component'; export const ROUTES: Routes = [ { path: '', component: HomeComponent } ]; @NgModule({ imports: [ BrowserModule, RouterModule.forRoot(ROUTES) ], // ... }) export class AppModule {}
示例中我們通過 path
屬性定義路由的匹配路徑,而 component
屬性用于定義路由匹配時需要加載的組件。
友情提示:我們使用 path: ''
來匹配空的路徑,例如:https://yourdomain.com
Displaying routes
配置完路由信息后,下一步是使用一個名為 router-outlet
的指令告訴 Angular 在哪里加載組件。當 Angular 路由匹配到響應路徑,并成功找到需要加載的組件時,它將動態創建對應的組件,并將其作為兄弟元素,插入到 router-outlet
元素中。
在我們 AppComponent
組件中,我們可以在任意位置插入 router-outlet
指令:
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <div class="app"> <h4>Our app</h4> <router-outlet></router-outlet> </div> ` }) export class AppComponent {}
我們現在已經建立了應用程序的主路由,我們可以進一步了解路由的其它配置選項。
Further configuration
到目前為止我們已經介紹的內容只是一個開始 ,接下來我們來看看其它一些選項和功能。
Dynamic routes
如果路由始終是靜態的,那沒有多大的用處。例如 path: ''
是加載我們 HomeComponent
組件的靜態路由。我們將介紹動態路由,基于動態路由我們可以根據不同的路由參數,渲染不同的頁面。
例如,如果我們想要在個人資料頁面根據不同的用戶名顯示不同的用戶信息,我們可以使用以下方式定義路由:
import { HomeComponent } from './home/home.component'; import { ProfileComponent } from './profile/profile.component'; export const ROUTES: Routes = [ { path: '', component: HomeComponent }, { path: '/profile/:username', component: ProfileComponent } ];
這里的關鍵點是 :
,它告訴 Angular 路由,:username
是路由參數,而不是 URL 中實際的部分。
友情提示:如果沒有使用 : ,它將作為靜態路由,僅匹配 /profile/username 路徑
現在我們已經建立一個動態路由,此時最重要的事情就是如何獲取路由參數。要訪問當前路由的相關信息,我們需要先從 @angular/router
模塊中導入 ActivatedRoute
,然后在組件類的構造函數中注入該對象,最后通過訂閱該對象的 params
屬性,來獲取路由參數,具體示例如下:
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'profile-page', template: ` <div class="profile"> <h4>{{ username }}</h4> </div> ` }) export class SettingsComponent implements OnInit { username: string; constructor(private route: ActivatedRoute) {} ngOnInit() { this.route.params.subscribe((params) => this.username = params.username); } }
介紹完動態路由,我們來探討一下如何創建 child routes
。
Child routes
實際上每個路由都支持子路由,假設在我們 /settings
設置頁面下有 /settings/profile
和 /settings/password
兩個頁面,分別表示個人資料頁和修改密碼頁。
我們可能希望我們的 / settings
頁面擁有自己的組件,然后在設置頁面組件中顯示 / settings/profile
和 / settings/password
頁面。我們可以這樣做:
import { SettingsComponent } from './settings/settings.component'; import { ProfileSettingsComponent } from './settings/profile/profile.component'; import { PasswordSettingsComponent } from './settings/password/password.component'; export const ROUTES: Routes = [ { path: 'settings', component: SettingsComponent, children: [ { path: 'profile', component: ProfileSettingsComponent }, { path: 'password', component: PasswordSettingsComponent } ] } ]; @NgModule({ imports: [ BrowserModule, RouterModule.forRoot(ROUTES) ], }) export class AppModule {}
在這里,我們在 setttings
路由中定義了兩個子路由,它們將繼承父路由的路徑,因此修改密碼頁面的路由匹配地址是 /settings/password
,依此類推。
接下來,我們需要做的最后一件事是在我們的 SettingsComponent
組件中添加 router-outlet
指令,因為我們要在設置頁面中呈現子路由。如果我們沒有在 SettingsComponent
組件中添加 router-outlet
指令,盡管 /settings/password
匹配修改密碼頁面的路由地址,但修改密碼頁面將無法正常顯示。具體代碼如下:
import { Component } from '@angular/core'; @Component({ selector: 'settings-page', template: ` <div class="settings"> <settings-header></settings-header> <settings-sidebar></settings-sidebar> <router-outlet></router-outlet> </div> ` }) export class SettingsComponent {}
Component-less routes
另一個很有用的路由功能是 component-less
路由。使用 component-less
路由允許我們將路由組合在一起,并讓它們共享路由配置信息和 outlet。
例如,我們可以定義 setttings
路由而不需要使用 SettingsComponent
組件:
import { ProfileSettingsComponent } from './settings/profile/profile.component'; import { PasswordSettingsComponent } from './settings/password/password.component'; export const ROUTES: Routes = [ { path: 'settings', children: [ { path: 'profile', component: ProfileSettingsComponent }, { path: 'password', component: PasswordSettingsComponent } ] } ]; @NgModule({ imports: [ BrowserModule, RouterModule.forRoot(ROUTES) ], }) export class AppModule {}
此時, /settings/profile
和 /settings/password
路由定義的內容,將顯示在 AppComponent
組件的 router-outlet
元素中。
loadChildren
我們也可以告訴路由從另一個模塊中獲取子路由。這將我們談論的兩個想法聯系在一起 - 我們可以指定另一個模塊中定義的子路由,以及通過將這些子路由設置到特定的路徑下,來充分利用 component-less
路由的功能。
讓我們創建一個 SettingsModule
模塊,用來保存所有 setttings
相關的路由信息:
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Routes, RouterModule } from '@angular/router'; export const ROUTES: Routes = [ { path: '', component: SettingsComponent, children: [ { path: 'profile', component: ProfileSettingsComponent }, { path: 'password', component: PasswordSettingsComponent } ] } ]; @NgModule({ imports: [ CommonModule, RouterModule.forChild(ROUTES) ], }) export class SettingsModule {}
需要注意的是,在 SettingsModule
模塊中我們使用 forChild()
方法,因為 SettingsModule
不是我們應用的主模塊。
另一個主要的區別是我們將 SettingsModule
模塊的主路徑設置為空路徑 ('')。因為如果我們路徑設置為 /settings
,它將匹配 /settings/settings
,很明顯這不是我們想要的結果。通過指定一個空的路徑,它就會匹配 /settings
路徑,這就是我們想要的結果。
那么 /settings
路由信息,需要在哪里配置?答案是在 AppModule
中。這時我們就需要用到 loadChildren
屬性,具體如下:
export const ROUTES: Routes = [ { path: 'settings', loadChildren: './settings/settings.module#SettingsModule' } ]; @NgModule({ imports: [ BrowserModule, RouterModule.forRoot(ROUTES) ], // ... }) export class AppModule {}
需要注意的是,我們沒有將 SettingsModule
導入到我們的 AppModule
中,而是通過 loadChildren
屬性,告訴 Angular 路由依據 loadChildren
屬性配置的路徑去加載 SettingsModule
模塊。這就是模塊懶加載功能的具體應用,當用戶訪問 /settings/**
路徑的時候,才會加載對應的 SettingsModule
模塊,這減少了應用啟動時加載資源的大小。
另外我們傳遞一個字符串作為 loadChildren
的屬性值,該字符串由三部分組成:
需要導入模塊的相對路徑
# 分隔符
導出模塊類的名稱
了解完路由的一些高級選項和功能,接下來我們來介紹路由指令。
Router Directives
除了 router-outlet
指令,路由模塊中還提供了一些其它指令。讓我們來看看它們如何與我們之前介紹的內容結合使用。
routerLink
為了讓我們鏈接到已設置的路由,我們需要使用 routerLink
指令,具體示例如下:
<nav> <a routerLink="/">Home</a> <a routerLink="/settings/password">Change password</a> <a routerLink="/settings/profile">Profile Settings</a> </nav>
當我們點擊以上的任意鏈接時,頁面不會被重新加載。反之,我們的路徑將在 URL 地址欄中顯示,隨后進行后續視圖更新,以匹配 routerLink
中設置的值。
友情提示:我們也可以將 routerLink 的屬性值,改成數組形式,以便我們傳遞特定的路由信息
如果我們想要鏈接到動態的路由地址,且該地址有一個 username
的路由變量,則我們可以按照以下方式配置 routerLink
對應的屬性值:
<a [routerLink]="['/profile', username]"> Go to {{ username }}'s profile. </a>
routerLinkActive
在實際開發中,我們需要讓用戶知道哪個路由處于激活狀態,通常情況下我們通過向激活的鏈接添加一個 class 來實現該功能。為了解決上述問題,Angular 路由模塊為我們提供了 routerLinkActive
指令,該指令的使用示例如下:
<nav> <a routerLink="/settings" routerLinkActive="active">Home</a> <a routerLink="/settings/password" routerLinkActive="active">Change password</a> <a routerLink="/settings/profile" routerLinkActive="active">Profile Settings</a> </nav>
通過使用 routerLinkActive
指令,當 a
元素對應的路由處于激活狀態時,active
類將會自動添加到 a
元素上。
最后,我們來簡單介紹一下 Router API。
Router API
我們可以通過路由還提供的 API 實現與 routerLink
相同的功能。要使用 Router API,我們需要在組件類中注入 Router
對象,具體如下:
import { Component } from '@angular/core'; import { Router } from '@angular/router'; @Component({ selector: 'app-root', template: ` <div class="app"> <h4>Our app</h4> <router-outlet></router-outlet> </div> ` }) export class AppComponent { constructor(private router: Router) {} }
組件類中注入的 router
對象中有一個 navigate()
方法,該方法支持的參數類型與 routerLink
指令一樣,當調用該方法后,頁面將會自動跳轉到對應的路由地址。具體使用示例如下:
import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; @Component({ selector: 'app-root', template: ` <div class="app"> <h4>Our app</h4> <router-outlet></router-outlet> </div> ` }) export class AppComponent implements OnInit { constructor(private router: Router) {} ngOnInit() { setTimeout(() => { this.router.navigate(['/settings']); }, 5000); } }
若以上代碼成功運行,用戶界面將在 5 秒后被重定向到 /settings
頁面。這個方法非常有用,例如當檢測到用戶尚未登錄時,自動重定向到登錄頁面。
另一個使用示例是演示頁面跳轉時如何傳遞數據,具體如下:
import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; @Component({ selector: 'app-root', template: ` <div class="app"> <h4>Users</h4> <div *ngFor="let user of users"> <user-component [user]="user" (select)="handleSelect($event)"> </user-component> </div> <router-outlet></router-outlet> </div> ` }) export class AppComponent implements OnInit { users: Username[] = [ { name: 'toddmotto', id: 0 }, { name: 'travisbarker', id: 1 }, { name: 'tomdelonge', id: 2 } ]; constructor(private router: Router) {} handleSelect(event) { this.router.navigate(['/profile', event.name]); } }
Angular 路由的功能非常強大,既可以使用指令方式也可以使用命令式 API,希望本文可以幫助你盡快入門,若要進一步了解路由詳細信息,請訪問 - Angular Router 官文文檔。
我有話說
除了使用 navigate()
方法外還有沒有其它方法可以實現頁面導航?
Angular Router API 為我們提供了 navigate()
和 navigateByUrl()
方法來實現頁面導航。那為什么會有兩個不同的方法呢?
使用 router.navigateByUrl()
方法與直接改變地址欄上的 URL 地址一樣,我們使用了一個新的 URL 地址。然而 router.navigate()
方法基于一系列輸入參數,產生一個新的 URL 地址。為了更好的區分它們之間的差異,我們來看個例子,假設當前的 URL 地址是:
/inbox/11/message/22(popup:compose)
當我們調用 router.navigateByUrl('/inbox/33/message/44')
方法后,此時的 URL 地址將變成 /inbox/33/message/44
。但如果我們是調用 router.navigate('/inbox/33/message/44')
方法,當前的 URL 地址將變成 /inbox/33/message/44(popup:compose)
。
感謝各位的閱讀!關于“Angular 4.x路由的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。