ルーティングは Angular アプリケーションの中核です。この記事では、Angular Router を理解し、navigate() と navigateByUrl() の使用法の違いを詳しく紹介します。
ルーティングは Angular アプリケーションの中心であり、要求されたルートに関連付けられたコンポーネントを読み込み、特定のルートに関連するデータを取得します。これにより、異なるルートを制御し、異なるデータを取得することで、異なるページをレンダリングできるようになります。 [関連チュートリアルの推奨事項: "angular チュートリアル"]
まず、Angular Router をインストールする必要があります。これを行うには、次の操作のいずれかを実行します。
yarn add @angular/router # OR npm i --save @angular/router
上記のコマンドを実行すると、@angular/router
モジュールが node_modules## に自動的にダウンロードされます。 # フォルダーの真ん中。
<base> タグを追加することです。ルーターはアプリケーションのルート ディレクトリを決定するためにこれを必要とします。たとえば、
http://example.com/page1 にアクセスするとき、アプリケーションのベース パスを定義しないと、ルーターはアプリケーションのホスティング アドレスが ## であることを認識できません。 #http:// /example.com
または http://example.com/page1
。 これは非常に簡単です。プロジェクト内の
ファイルを開き、次のように対応する <base>
タグを追加するだけです:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:html;toolbar:false;"><!doctype html>
<html>
<head>
<base href="/">
<title>Application</title>
</head>
<body>
<app-root></app-root>
</body>
</html></pre><div class="contentsignin">ログイン後にコピー</div></div>
上記の構成情報は、アプリケーションのルート ディレクトリが
であることを Angular ルーティングに伝えます。
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 オブジェクトは、ルーティング情報を構成するための 2 つの静的メソッド
forRoot() と forChild()
を提供します。
メソッドは、メイン モジュール内の主要なルーティング情報を定義するために使用されます。このメソッドにより、メイン モジュールはルーティング モジュールで定義されたすべてのディレクティブにアクセスできるようになります。次に、forRoot()
の使用方法を見てみましょう。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">// ...
import { Routes, RouterModule } from &#39;@angular/router&#39;;
export const ROUTES: Routes = [];
@NgModule({
imports: [
BrowserModule,
RouterModule.forRoot(ROUTES)
],
// ...
})
export class AppModule {}</pre><div class="contentsignin">ログイン後にコピー</div></div>
const を使用してルーティング構成情報を定義し、それをパラメータとして呼び出します
RouterModule.forRoot([...]) を直接使用する代わりに ()
メソッドを使用します。このメソッドの利点は、ROUTES
を他のファイルにエクスポートするのに便利であることです。必要に応じてモジュールを追加します。
は Router.forRoot()
メソッドに似ています。ただし、機能モジュールでのみ使用できます。 わかりやすいリマインダー: ルート モジュールでは
forRoot()
を使用し、サブモジュールでは forChild()
を使用してください。この関数は非常に強力です。すべてのルーティング情報を 1 か所 (メイン モジュール) で定義します。代わりに、機能モジュールでモジュール固有のルーティング情報を定義し、必要に応じてそれらをメイン モジュールにインポートできます。
RouterModule.forChild()
は次のように使用されます。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">import { NgModule } from &#39;@angular/core&#39;;
import { CommonModule } from &#39;@angular/common&#39;;
import { Routes, RouterModule } from &#39;@angular/router&#39;;
export const ROUTES: Routes = [];
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(ROUTES)
],
// ...
})
export class ChildModule {}</pre><div class="contentsignin">ログイン後にコピー</div></div>
上記の例を通じて、ルーティング構成オブジェクトのタイプがメイン モジュールとフィーチャー モジュールで同じであることがわかります。違いはメイン モジュールのみです。モジュール ルーティングを設定するには、フィーチャー モジュールで異なるメソッドを呼び出す必要があります。次に、
オブジェクトを構成する方法を紹介します。
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
ルートの表示
router-outlet 要素に挿入されます。
AppComponent コンポーネントでは、任意の場所に
router-outlet
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <div class="app"> <h3>Our app</h3> <router-outlet></router-outlet> </div> ` }) export class AppComponent {}
これでアプリケーションのメイン ルートが確立されました。さらに詳しく学習します。ルーティングのその他の構成オプションについて。
さらなる構成
如果路由始终是静态的,那没有多大的用处。例如 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>{{ 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。
实际上每个路由都支持子路由,假设在我们 /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 路由。使用 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
元素中。
我们也可以告诉路由从另一个模块中获取子路由。这将我们谈论的两个想法联系在一起 - 我们可以指定另一个模块中定义的子路由,以及通过将这些子路由设置到特定的路径下,来充分利用 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-outlet
指令,路由模块中还提供了一些其它指令。让我们来看看它们如何与我们之前介绍的内容结合使用。
为了让我们链接到已设置的路由,我们需要使用 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>
在实际开发中,我们需要让用户知道哪个路由处于激活状态,通常情况下我们通过向激活的链接添加一个 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。
我们可以通过路由还提供的 API 实现与 routerLink 相同的功能。要使用 Router API,我们需要在组件类中注入 Router 对象,具体如下:
import { Component } from '@angular/core'; import { Router } from '@angular/router'; @Component({ selector: 'app-root', template: ` <div class="app"> <h3>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>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>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
<a [routerLink]="['/router', '823712312938123', {h:'h',c:'c'}]" [queryParams]="{code:'code'}">RouterLink 跳转</a> <a (click)="goToDetail()">Navigate 跳转</a>
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 中国語 Web サイトの他の関連記事を参照してください。