Angularでのルーティングの完全ガイド
公開: 2022-03-10まだAngular7に慣れていない場合は、この印象的なフロントエンドフレームワークが提供するすべてのものに近づきたいと思います。 次のような、ルーターに関連するさまざまな概念を示すAngularデモアプリについて説明します。
- ルーターアウトレット、
- ルートとパス、
- ナビゲーション。
また、Angular CLI v7を使用してデモプロジェクトを生成する方法も示します。ここでは、Angularルーターを使用してルーティングとナビゲーションを実装します。 ただし、最初に、Angularを紹介し、最新バージョンの重要な新機能のいくつかについて説明します。
Angular7の紹介
Angularは、モバイルおよびデスクトップWeb用のクライアント側Webアプリケーションを構築するための最も人気のあるフロントエンドフレームワークの1つです。 これは、各コンポーネントがアプリのUIの一部を制御する、分離された再利用可能なコードであるコンポーネントベースのアーキテクチャに従います。
Angularのコンポーネントは、 @Component
デコレータで装飾されたTypeScriptクラスです。 コンポーネントのビューを形成するテンプレートとCSSスタイルシートが添付されています。
Angularの最新バージョンであるAngular7が最近リリースされ、特にCLIツールとパフォーマンスの新機能が次のように追加されました。
- CLIプロンプト:
ng add
やng new
などの一般的なコマンドで、ルーティングやスタイルシート形式など、プロジェクトに追加する機能を選択するようにユーザーに求めることができるようになりました。 - Angular Material CDK(コンポーネントDevKit)にスクロールを追加します。
- Angular MaterialCDKにドラッグアンドドロップのサポートを追加します。
- プロジェクトは、アプリがサイズ制限を超えたときに開発者に警告する予算バンドルを使用するようにデフォルト設定されています。 デフォルトでは、サイズが2MBを超え、5MBでエラーが発生すると、警告がスローされます。 これらの制限は、
angular.json
ファイルで変更することもできます。 等
Angularルーターの紹介
Angular Routerは、Angularコアチームによって構築および保守されている強力なJavaScriptルーターであり、 @angular/router
パッケージからインストールできます。 複数のルーターアウトレット、さまざまなパスマッチング戦略、ルートパラメータへの簡単なアクセス、およびコンポーネントを不正アクセスから保護するためのルートガードを備えた、完全なルーティングライブラリを提供します。
AngularルーターはAngularプラットフォームのコア部分です。 これにより、開発者は複数のビューを備えたシングルページアプリケーションを構築し、これらのビュー間のナビゲーションを可能にします。
ここで、ルーターの基本的な概念について詳しく見ていきましょう。
ルーターアウトレット
Router-Outlet
は、ルーターライブラリから利用できるディレクティブであり、ルーターは、現在のブラウザーのURLに基づいて照合されるコンポーネントを挿入します。 Angularアプリケーションに複数のアウトレットを追加して、高度なルーティングシナリオを実装できます。
<router-outlet></router-outlet>
ルーターによって一致するコンポーネントは、ルーターアウトレットの兄弟としてレンダリングされます。
ルートとパス
ルートは、少なくともパスとコンポーネント(またはredirectToパス)属性から構成される定義(オブジェクト)です。 パスは、表示する必要のある一意のビューを決定するURLの部分を指し、コンポーネントは、パスに関連付ける必要のあるAngularコンポーネントを指します。 (静的RouterModule.forRoot(routes)
メソッドを介して)提供するルート定義に基づいて、ルーターはユーザーを特定のビューにナビゲートできます。
各Route
は、URL path
をコンポーネントにマップします。
パスは空にすることができます。これは、アプリケーションのデフォルトパスを示し、通常はアプリケーションの開始です。
パスはワイルドカード文字列( **
)を取ることができます。 要求されたURLが定義されたルートのどのパスとも一致しない場合、ルーターはこのルートを選択します。 これは、「見つかりません」ビューを表示したり、一致するものが見つからない場合に特定のビューにリダイレクトしたりするために使用できます。
これはルートの例です:
{ path: 'contacts', component: ContactListComponent}
このルート定義がルーター構成に提供されている場合、WebアプリケーションのブラウザーURLが/contacts
になると、ルーターはContactListComponent
をレンダリングします。
ルートマッチング戦略
Angularルーターはさまざまなルートマッチング戦略を提供します。 デフォルトの戦略は、現在のブラウザのURLの前にパスが付いているかどうかを確認するだけです。
たとえば、以前のルート:
{ path: 'contacts', component: ContactListComponent}
次のように書くこともできます:
{ path: 'contacts',pathMatch: 'prefix', component: ContactListComponent}
patchMath
属性は、マッチング戦略を指定します。 この場合、デフォルトのプレフィックスです。
2番目のマッチング戦略は完全です。 ルートに指定すると、ルーターはパスが現在のブラウザのURLのパスと完全に等しいかどうかを確認します。
{ path: 'contacts',pathMatch: 'full', component: ContactListComponent}
ルートパラメータ
パラメータを使用してルートを作成することは、Webアプリの一般的な機能です。 Angular Routerを使用すると、さまざまな方法でパラメーターにアクセスできます。
- ActivatedRouteサービスを使用して、
- v4以降で利用可能なParamMapobservableを使用します。
コロン構文を使用してルートパラメータを作成できます。 これは、 idパラメーターを使用したルートの例です。
{ path: 'contacts/:id', component: ContactDetailComponent}
ルートガード
ルートガードはAngularRouterの機能であり、ルートが要求されたときに開発者がロジックを実行できるようにし、そのロジックに基づいて、ルートへのユーザーアクセスを許可または拒否します。 これは通常、ユーザーがページにアクセスする前に、ユーザーがログインして認証を持っているかどうかを確認するために使用されます。
@angular/router
パッケージから利用可能なCanActivate
インターフェースを実装し、ルートへのアクセスを許可または拒否するロジックを保持するcanActivate()
メソッドを拡張することにより、ルートガードを追加できます。 たとえば、次のガードは常にルートへのアクセスを許可します。
class MyGuard implements CanActivate { canActivate() { return true; } }
次に、 canActivate
属性を使用して、ガードでルートを保護できます。
{ path: 'contacts/:id, canActivate:[MyGuard], component: ContactDetailComponent}
ナビゲーションディレクティブ
Angular Routerは、ナビゲーションリンクを作成するためのrouterLink
ディレクティブを提供します。 このディレクティブは、ナビゲートするコンポーネントに関連付けられたパスを取ります。 例えば:
<a [routerLink]="'/contacts'">Contacts</a>
複数のアウトレットと補助ルート
Angular Routerは、同じアプリケーションで複数のアウトレットをサポートします。
コンポーネントには1つのプライマリルートが関連付けられており、補助ルートを持つことができます。 補助ルートを使用すると、開発者は同時に複数のルートをナビゲートできます。
補助ルートを作成するには、補助ルートに関連付けられているコンポーネントが表示される名前付きルーターアウトレットが必要です。
<router-outlet></router-outlet> <router-outlet name="outlet1"></router-outlet>
- 名前のないコンセントがプライマリコンセントです。
- プライマリアウトレットを除くすべてのアウトレットには名前を付ける必要があります。
次に、outlet属性を使用して、コンポーネントをレンダリングするアウトレットを指定できます。
{ path: "contacts", component: ContactListComponent, outlet: "outlet1" }
Angular7デモプロジェクトの作成
このセクションでは、Angularルーターをセットアップして操作する方法の実際的な例を示します。 作成するライブデモとプロジェクトのGitHubリポジトリを確認できます。
Angular CLIv7のインストール
Angular CLIには、 NPM5.5.1以降のノード8.9以降が必要です。 これらの要件がシステムにインストールされていることを確認してから、次のコマンドを実行して最新バージョンのAngularCLIをインストールする必要があります。
$ npm install -g @angular/cli
これにより、AngularCLIがグローバルにインストールされます。
注: npmの構成によっては、 sudo
を使用してパッケージをグローバルにインストールすることをお勧めします。
Angular7プロジェクトの作成
新しいプロジェクトの作成は1つのコマンドで、次のコマンドを実行するだけです。
$ ng new angular7-router-demo
CLIは、ルーティングを追加するかどうか(ルーティングを手動で追加する方法を説明するため、[いいえ]にN
を入力)と、使用するスタイルシート形式を尋ねます。最初のオプションであるCSSを選択し、 Enter
を押します。 CLIは、必要なファイルを含むフォルダー構造を作成し、プロジェクトに必要な依存関係をインストールします。
偽のバックエンドサービスの作成
対話する実際のバックエンドがないため、Angularデモおよびテスト用のメモリ内WebAPIであるangular-in-memory-web-api
ライブラリを使用して偽のバックエンドを作成します。 RESTAPIを介してCRUD操作をエミュレートします。
これは、リモートサーバーに送信されたHttpClient
要求をインターセプトし、作成する必要のあるローカルのメモリ内データストアにリダイレクトすることで機能します。
偽のバックエンドを作成するには、次の手順に従う必要があります。
- まず、
angular-in-memory-web-api
モジュールをインストールします。 - 次に、偽のデータを返すサービスを作成します。
- 最後に、偽のバックエンドを使用するようにアプリケーションを構成します。
ターミナルで次のコマンドを実行して、npmからangular-in-memory-web-api
モジュールをインストールします。
$ npm install --save angular-in-memory-web-api
次に、以下を使用してバックエンドサービスを生成します。
$ ng gs backend
src/app/backend.service.ts
ファイルを開き、 angular-in-memory-web-api
モジュールからInMemoryDbService
をインポートします。
import {InMemoryDbService} from 'angular-in-memory-web-api'
サービスクラスはInMemoryDbService
を実装してから、 createDb()
メソッドをオーバーライドする必要があります。
@Injectable({ providedIn: 'root' }) export class BackendService implements InMemoryDbService{ constructor() { } createDb(){ let contacts = [ { id: 1, name: 'Contact 1', email: '[email protected]' }, { id: 2, name: 'Contact 2', email: '[email protected]' }, { id: 3, name: 'Contact 3', email: '[email protected]' }, { id: 4, name: 'Contact 4', email: '[email protected]' } ]; return {contacts}; } }
連絡先の配列を作成して返すだけです。 各連絡先にはIDが必要です。
最後に、 InMemoryWebApiModule
をapp.module.ts
ファイルにインポートし、偽のバックエンドサービスを提供する必要があります。
import { InMemoryWebApiModule } from “angular-in-memory-web-api”; import { BackendService } from “./backend.service”; /* ... */ @NgModule({ declarations: [ /*...*/ ], imports: [ /*...*/ InMemoryWebApiModule.forRoot(BackendService) ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
次に、連絡先を操作するためのコードをカプセル化するContactService
を作成します。
$ ng gs contact
src/app/contact.service.ts
ファイルを開き、次のコードのように更新します。
import { Injectable } from '@angular/core'; import { HttpClient } from “@angular/common/http”; @Injectable({ providedIn: 'root' }) export class ContactService { API_URL: string = "/api/"; constructor(private http: HttpClient) { } getContacts(){ return this.http.get(this.API_URL + 'contacts') } getContact(contactId){ return this.http.get(`${this.API_URL + 'contacts'}/${contactId}`) } }
2つのメソッドを追加しました。
-
getContacts()
すべての連絡先を取得します。 -
getContact()
IDで連絡先を取得します。
実際のバックエンドを使用しないため、 API_URL
を任意のURLに設定できます。 すべてのリクエストはインターセプトされ、メモリ内のバックエンドに送信されます。
Angularコンポーネントの作成
さまざまなルーター機能の使用方法を確認する前に、まずプロジェクトに一連のコンポーネントを作成しましょう。
ターミナルに向かい、次のコマンドを実行します。
$ ng gc contact-list $ ng gc contact-detail
これにより、2つのContactListComponent
コンポーネントとContactDetailComponent
コンポーネントが生成され、メインのアプリモジュールに追加されます。
ルーティングの設定
ほとんどの場合、Angular CLIを使用してルーティング設定のあるプロジェクトを作成しますが、この場合は手動で追加して、Angularでルーティングがどのように機能するかをよりよく理解できるようにします。
ルーティングモジュールの追加
AppRoutingModule
を追加する必要があります。これには、アプリケーションルートと、ブラウザーの現在のURLに応じてAngularが現在一致しているコンポーネントを挿入するルーターアウトレットが含まれます。
表示されます:
- ルーティング用のAngularモジュールを作成してインポートする方法。
- さまざまなコンポーネントにルートを追加する方法。
- ルーターコンセントを追加する方法。
まず、 app-routing.module.ts
ファイルにルーティングモジュールを作成することから始めましょう。 src/app
内で、以下を使用してファイルを作成します。
$ cd angular7-router-demo/src/app $ touch app-routing.module.ts
ファイルを開き、次のコードを追加します。
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; const routes: Routes = []; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
まず、Angularモジュールの作成に使用されるTypeScriptデコレータである@angular/core
パッケージからNgModule
をインポートします。
また、 RouterModule
クラスとRoutes
クラスを@angular/router
パッケージからインポートします。 RouterModule
は、構成オブジェクトをルーターに渡すためのRouterModule.forRoot()
のような静的メソッドを提供します。
次に、各ルートの情報を保持するために使用されるRoutes
タイプの定数routes
配列を定義します。
最後に、 AppRoutingModule
(任意の名前を付けることができます)というモジュールを作成してエクスポートします。これは、メタ情報オブジェクトを@NgModule
デコレータで装飾されたTypeScriptクラスです。 このオブジェクトのimports
属性では、routes配列をパラメーターとして使用して静的RouterModule.forRoot(routes)
メソッドを呼び出します。 exports
配列に、 RouterModule
を追加します。
ルーティングモジュールのインポート
次に、このモジュールルーティングをsrc/app/app.module.ts
ファイルにあるメインアプリモジュールにインポートする必要があります。
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
./app-routing.module
をAppRoutingModule
からインポートし、メインモジュールのimports
配列に追加します。
ルーターアウトレットの追加
最後に、ルーターのコンセントを追加する必要があります。 メインのアプリテンプレートを含むsrc/app/app.component.html
ファイルを開き、 <router-outlet>
コンポーネントを追加します。
<router-outlet></router-outlet>
これは、AngularRouterが現在のブラウザのパスに対応するコンポーネントをレンダリングする場所です。
Angularプロジェクト内でルーティングを手動で設定するために必要な手順はこれだけです。
ルートの作成
次に、2つのコンポーネントにルートを追加しましょう。 src/app/app-routing.module.ts
ファイルを開き、次のルートをroutes
配列に追加します。
const routes: Routes = [ {path: 'contacts' , component: ContactListComponent}, {path: 'contact/:id' , component: ContactDetailComponent} ];
ルーティングモジュールに2つのコンポーネントをインポートしてください。
import { ContactListComponent } from './contact-list/contact-list.component'; import { ContactDetailComponent } from './contact-detail/contact-detail.component';
これで、 /contacts
パスとcontact/:id
パスから2つのコンポーネントにアクセスできます。
ナビゲーションリンクの追加
次に、 routerLink
ディレクティブを使用して、アプリテンプレートにナビゲーションリンクを追加しましょう。 src/app/app.component.html
を開き、ルーターアウトレットの上に次のコードを追加します。
<h2><a [routerLink] = "'/contacts'">Contacts</a></h2>
次に、 ContactListComponent
に連絡先のリストを表示する必要があります。 src/app/contact-list.component.ts
を開き、次のコードを追加します。
import { Component, OnInit } from '@angular/core'; import { ContactService } from '../contact.service'; @Component({ selector: 'app-contact-list', templateUrl: './contact-list.component.html', styleUrls: ['./contact-list.component.css'] }) export class ContactListComponent implements OnInit { contacts: any[] = []; constructor(private contactService: ContactService) { } ngOnInit() { this.contactService.getContacts().subscribe((data : any[])=>{ console.log(data); this.contacts = data; }) } }
連絡先を保持するためのcontacts
配列を作成します。 次に、 ContactService
を挿入し、インスタンスのgetContacts()
メソッドを( ngOnInit
ライフサイクルイベントで)呼び出して連絡先を取得し、 contacts
配列に割り当てます。
次に、 src/app/contact-list/contact-list.component.html
ファイルを開き、以下を追加します。
<table> <tr> <th>Name</th> <th>Email</th> <th>Actions</th> </tr> <tr *ngFor="let contact of contacts" > <td>{{ contact.name }}</td> <td>{{ contact.email }}</td> <td> <a [routerLink]="['/contact', contact.id]">Go to details</a> </td> </tr> </table>
連絡先をループして、各連絡先の名前と電子メールを表示します。 また、 routerLink
ディレクティブを使用して、各連絡先の詳細コンポーネントへのリンクを作成します。
これは、コンポーネントのスクリーンショットです。
[詳細に移動]リンクをクリックすると、 ContactDetailsComponent
に移動します。 ルートにはid
パラメータがあります。コンポーネントからルートにアクセスする方法を見てみましょう。
src/app/contact-detail/contact-detail.component.ts
ファイルを開き、次のコードのようにコードを変更します。
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { ContactService } from '../contact.service'; @Component({ selector: 'app-contact-detail', templateUrl: './contact-detail.component.html', styleUrls: ['./contact-detail.component.css'] }) export class ContactDetailComponent implements OnInit { contact: any; constructor(private contactService: ContactService, private route: ActivatedRoute) { } ngOnInit() { this.route.paramMap.subscribe(params => { console.log(params.get('id')) this.contactService.getContact(params.get('id')).subscribe(c =>{ console.log(c); this.contact = c; }) }); } }
ContactService
とActivatedRoute
をコンポーネントに挿入します。 ngOnInit()
ライフサイクルイベントでは、ルートから渡されるidパラメータを取得し、それを使用して、 contact
オブジェクトに割り当てる連絡先の詳細を取得します。
src/app/contact-detail/contact-detail.component.html
ファイルを開き、以下を追加します。
<h1> Contact # {{contact.id}}</h1> <p> Name: {{contact.name}} </p> <p> Email: {{contact.email}} </p>
127.0.0.1:4200/
から最初にアプリケーションにアクセスしたとき、アウトレットはコンポーネントをレンダリングしないため、routes配列に次のルートを追加して、空のパスをcontacts
パスにリダイレクトしましょう。
{path: '', pathMatch: 'full', redirectTo: 'contacts'}
完全な空のパスを一致させたいので、完全一致戦略を指定します。
結論
このチュートリアルでは、Angularルーターを使用してアプリケーションにルーティングとナビゲーションを追加する方法を説明しました。 ルーターのコンセント、ルート、パスなどのさまざまな概念を確認し、さまざまな概念を実際に示すためのデモを作成しました。 このリポジトリからコードにアクセスできます。