HTML5テクニカルノート
Angular 4入門 06: Routerを使う
- ID: FN1706006
- Technique: HTML5 / JavaScript
- Package: Angular 4.0
「Angular 4入門 05: リスト表示のコンポーネントを分ける」(以下「Angular 4入門 05」)の作例(コード001)では、コンポーネントのモジュールからリストのコンポーネントを分けました。さらに、Routerでページに加えるコンポーネントを切り替えましょう。Routerは、ページの表示やURLのパスを変えるナビゲーションの仕組みです。
Angular Version 5については「Angular 5入門 06: ルーティングで画面を切り替える」をお読みください。
01 Routerを加える
メインのコンポーネント(app.component)は、子コンポーネントの表示をナビゲートして切り替えることが役割になりました。そのためには、Routerを加えて設定しなければなりません。ナビゲーションには、ブラウザのアドレスバーに示すURLも含みます。まず、HTMLドキュメント(index.html)に加えなければならないのは、base
要素にhref
属性の定めです。すでに「Angular 4入門 01」コード001で、つぎのように書き加えておきました。
index.html<head> <base href="/"> </head>
アプリケーションのモジュール(app.module)には、RouterModule
クラスをimport
します。すると、NgModule()
デコレータ関数に渡す引数のオブジェクトのimports
プロパティに、RouterModule.forRoot()
メソッドでつぎのようにURLのパス(path
プロパティ)と表示するコンポーネント(component
ブロパティ)が定められます。画面を遷移したとき、ブラウザのアドレスバーにはこのパスが加わり、コンポーネントが表示されるのです。
app.module.tsimport {RouterModule} from '@angular/router'; @NgModule({ imports: [ FormsModule, RouterModule.forRoot([ { path: 'heroines', component: HeroinesComponent } ]) ], }) export class AppModule {}
つぎに、上記で定めたパスにいつ切り替え、コンポーネントをどこに表示するかです。メインのコンポーネント(app.component)のコードは、つぎのように書き替えます。<a>
要素のリンクで切り替えるため、RouterLink
ディレクティブにパスを与えます。そして、RouterOutletディレクティブ
を加えれば、リンクしたパスのコンポーネントがそこに差し込まれます(図001)。書き替えたふたつのモジュールは、以下のコード001にまとめました。
app.component.ts@Component({ template: ` <h1>{{title}}</h1> <a routerLink="/heroines">ヒロインたち</a> <router-outlet></router-outlet> ` /* <my-heroines></my-heroines> ` */ }) export class AppComponent { }
図001■リンクをクリックすると下にリストが表れる
コード001■アプリケーションとメインのコンポーネント
app.module.ts
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {FormsModule} from '@angular/forms';
import {RouterModule} from '@angular/router';
import {AppComponent} from './app.component';
import {HeroineDetailComponent} from './heroine-detail.component';
import {HeroinesComponent} from './heroines.component';
import {HeroineService} from './heroine.service';
@NgModule({
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot([
{
path: 'heroines',
component: HeroinesComponent
}
])
],
declarations: [
AppComponent,
HeroineDetailComponent,
HeroinesComponent
],
providers: [HeroineService],
bootstrap: [AppComponent]
})
export class AppModule {}
import {Component} from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h1>{{title}}</h1>
<a routerLink="/heroines">ヒロインたち</a>
<router-outlet></router-outlet>
`
})
export class AppComponent {
title = 'ヒロイン一覧';
}
02 ダッシュボードのコンポーネントを加える
初めにデフォルトとして、項目リストより先にダッシュボードを表示することにします。そのコンポーネント(dashboard.component)をつぎのように定めましょう。テンプレートはとりあえず「ダッシュボード」というテキストを示すだけです。
dashboard.component.tsimport {Component} from '@angular/core'; @Component({ selector: 'my-dashboard', template: '<h3>ダッシュボード</h3>' }) export class DashboardComponent {}
アプリケーションのモジュール(app.module)に、つぎのようにデコレータ関数(NgModule()
)の引数でコンポーネント(DashboardComponent)を加えます。RouterModule.forRoot()
メソッドには、パス(dashboard)を定めたほか、指定がない('')ときのデフォルト転送先(redirectTo
)としました(「Redirecting routes」参照)。そして、declarations
の配列に納めています。
app.module.tsimport {DashboardComponent} from './dashboard.component'; @NgModule({ imports: [ RouterModule.forRoot([ { path: '', redirectTo: '/dashboard', pathMatch: 'full' }, { path: 'dashboard', component: DashboardComponent }, ]) ], declarations: [ AppComponent, DashboardComponent, ], }) export class AppModule {}
メインのコンポーネントには、つぎのように<a>
要素でダッシュボードへのリンクを加え、ふたつ合わせて<nav>
要素に含めます。パス(dashboard)はrouterLink
ディレクティブで与えます。これで、初めにダッシュボードが表示されるようになりました(図002)。
app.component.ts@Component({ template: ` <nav> <a routerLink="/dashboard">ダッシュボード</a> <a routerLink="/heroines">ヒロインたち</a> </nav> ` }) export class AppComponent { }
図002■初めにダッシュボードが表示される
03 ダッシュボードに上位のリストを示す
ダッシュボードには、リストの上位4項目を掲げましょう。コンポーネントのクラス(DashboardComponent)に以下のようにOnInit
クラスを実装し、コンストラクタでサービス(HeroineService)のインスタンスをプロパティ(heroineService)に与えます(OnInit
クラスについては「Angular 4入門 04」02「コンポーネントのモジュールを書き替える」参照)。そして、ngOnInit()
メソッドが呼び出されたとき、プロパティ(heroines)のリスト項目からArray.slice()
メソッドで取り出した上位4つのエレメントを配列でプロパティ(heroines)に定めました。テンプレートは外部ファイル(dashboard.component.html)とし、デコレータ関数(Component()
)にパスをプロパティtemplateUrl
で定めました。パスはコンポーネントからの相対パスで、必ず'./'で始めてください(「Angular 4でmoduleIdは要らなくなる」参照)。
dashboard.component.ts// import {Component} from '@angular/core'; import {Component, OnInit} from '@angular/core'; import {Heroine} from './heroine'; import {HeroineService} from './heroine.service'; @Component({ selector: 'my-dashboard', // template: '<h3>ダッシュボード</h3>' templateUrl: './dashboard.component.html' }) // export class DashboardComponent {} export class DashboardComponent implements OnInit { heroines: Heroine[] = []; constructor(private heroineService: HeroineService) {} ngOnInit(): void { this.heroineService.getHeroines() .then((heroines: Heroine[]) => this.heroines = heroines.slice(0, 4)); } }
ひとつ補っておきたいのは、サービス(HeroineService)のメソッドの呼び出しについてです。サービスは親のアプリケーションのモジュール(app.module)でデコレータ関数(NgModule()
)の引数オブジェクトにproviders
として配列エレメントに加えてありました(「Angular 4入門 05」02「アプリケーションのモジュールにリスト表示のコンポーネントを組み込む」)。そうすることで、子のコンポーネントがサービスの同じインスタンスを使えるのです。
app.module.tsimport {HeroineService} from './heroine.service'; @NgModule({ providers: [HeroineService], }) export class AppModule {}
テンプレートはつぎのようにngFor
ディレクティブで、プロパティ(heroines)の配列から取り出した項目を順に要素に加えています(図003)。ダッシュボードを加えるために書き替えた3つのモジュールは、以下のコード002にまとめたとおりです。併せて、Plunkerに作例のコードを掲げます。
dashboard.component.html<h3>トップヒロイン</h3> <div class="grid grid-pad"> <div *ngFor="let heroine of heroines" class="col-1-4"> <div class="module heroine"> <h4>{{heroine.name}}</h4> </div> </div> </div>
図003■ダッシュボードに示された上位のリスト
コード002■ダッシュボードを加えるために書き替えた3つのモジュール
dashboard.component.ts
import {Component, OnInit} from '@angular/core';
import {Heroine} from './heroine';
import {HeroineService} from './heroine.service';
@Component({
selector: 'my-dashboard',
templateUrl: './dashboard.component.html'
})
export class DashboardComponent implements OnInit {
heroines: Heroine[] = [];
constructor(private heroineService: HeroineService) {}
ngOnInit(): void {
this.heroineService.getHeroines()
.then((heroines: Heroine[]) => this.heroines = heroines.slice(0, 4));
}
}
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {FormsModule} from '@angular/forms';
import {RouterModule} from '@angular/router';
import {AppComponent} from './app.component';
import {HeroineDetailComponent} from './heroine-detail.component';
import {HeroinesComponent} from './heroines.component';
import {HeroineService} from './heroine.service';
import {DashboardComponent} from './dashboard.component';
@NgModule({
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot([
{
path: '',
redirectTo: '/dashboard',
pathMatch: 'full'
},
{
path: 'dashboard',
component: DashboardComponent
},
{
path: 'heroines',
component: HeroinesComponent
}
])
],
declarations: [
AppComponent,
DashboardComponent,
HeroineDetailComponent,
HeroinesComponent
],
providers: [HeroineService],
bootstrap: [AppComponent]
})
export class AppModule {}
import {Component} from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h1>{{title}}</h1>
<nav>
<a routerLink="/dashboard">ダッシュボード</a>
<a routerLink="/heroines">ヒロインたち</a>
</nav>
<router-outlet></router-outlet>
`
})
export class AppComponent {
title = 'ヒロイン一覧';
}
- Angular 4: とにかくAngular 4でコードを書いて動かす
- Angular 4入門 01: 編集ページをつくる
- Angular 4入門 02: リストを加える
- Angular 4入門 03: コンポーネントを分ける
- Angular 4入門 04: サービスをつくる
- Angular 4入門 05: リスト表示のコンポーネントを分ける
- Angular 4入門 07: Routerで画面を遷移させる
- Angular 4入門 08: HTTPサービスでデータを取得・保存する
- Angular 4入門 09: HTTPサービスでデータを追加・削除する
作成者: 野中文雄
更新日: 2017年6月18日 03「ダッシュボードに上位のリストを示す」に、サービスのメソッド呼び出しについて補足。
更新日: 2017年6月13日 03「ダッシュボードに上位のリストを示す」に、相対パスの書き方についての注意と参考記事へのリンクを追加。
作成日: 2017年6月8日
Copyright © 2001-2017 Fumio Nonaka. All rights reserved.