路由是Angular應用程式的核心,這篇文章帶大家了解Angular Router,詳細介紹一下navigate()和navigateByUrl()用法的差別。
路由是 Angular 應用程式的核心,它會載入與所請求路由相關聯的元件,以及取得特定路由的相關資料。這允許我們透過控制不同的路由,獲取不同的數據,從而渲染不同的頁面。 【相關教學推薦:《angular教學》】
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="/"> <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"> <h3 id="Our-nbsp-app">Our app</h3> <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"> <h3 id="nbsp-username-nbsp">{{ username }}</h3> </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: () => import('./settings/settings.module').then(it => it.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"> <h3 id="Our-nbsp-app">Our app</h3> <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"> <h3 id="Our-nbsp-app">Our app</h3> <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"> <h3 id="Users">Users</h3> <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 官文文档。
路由传参示例/router/823712312938123;h=h;c=c?code=code
- HTML:
<a [routerLink]="['/router', '823712312938123', {h:'h',c:'c'}]" [queryParams]="{code:'code'}">RouterLink 跳转</a> <a (click)="goToDetail()">Navigate 跳转</a>
- TS:
this.router.navigate([`router/823712312938123`, {h: 'h', c: 'c'}], {queryParams: {code: 'code'}})
在component中取数据
router-demo.component.ts
import {Component, OnInit} from '@angular/core' import {ActivatedRoute} from '@angular/router' @Component({ selector: 'app-router-demo', templateUrl: './router-demo.component.html', styleUrls: ['./router-demo.component.less'] }) export class RouterDemoComponent implements OnInit { constructor(private activatedRoute: ActivatedRoute) { } ngOnInit(): void { const {params, queryParams} = this.activatedRoute.snapshot console.log('params', params) console.log('queryParams', queryParams, queryParams) } }
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中navigate()和navigateByUrl()使用方法的區別的詳細內容。更多資訊請關注PHP中文網其他相關文章!

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

SublimeText3 Linux新版
SublimeText3 Linux最新版

Dreamweaver Mac版
視覺化網頁開發工具