Edited at

Angularでスライドショー(1) 〜Routerでページの切り替え〜

More than 1 year has passed since last update.


はじめに

この記事では、Angularでスライドショーを作成する方法について説明します。

第1回目は、Router(ルーター)機能を使ったページの切り替えについてです。

(環境は、この記事の執筆時点の最新バージョンである Angular 4.3.4 です)

解説はいつものとおり「恋に落ちるコード.js」の絵子と樹里がお送りします。


人物紹介

瀬尾絵子:「恋に落ちるコード.js」の登場人物。JavaScript勉強中の女子高生。

篠宮樹里: 同じく「恋に落ちるコード.js」の登場人物。JavaScriptに詳しい女子高生。


目的

樹里「絵子、Angular CLIでスライドショーを作ってみよう」

絵子「相変わらず話が唐突だね。何でまた急に」

樹里「先日、同じくAngular CLIでRedmineのチケットの一覧を表示するWebアプリを作成したが」

絵子「うん。カンタンに出来るもんだなー、とビックリしちゃった」

樹里「Redmineで管理されているタスクは、結局のところRedmineにアクセスしないと確認できない。故に、常にRedmineを確認する習慣を付けないと見落としが発生する」

絵子「確かに。習慣を根付かせるまでは大変だよね」

樹里「そこで、APIからチケットの情報を取得してスライドショー形式で表示させれば、Redmineを開かずともタスクを確認することができる」

絵子「自然と目に入るもんね」

樹里「膨大なタスクの数にウンザリするも良し、いつまでも片付かない長寿タスクにウンザリするも良し」

絵子「何が良しなのかわからないけど、でも見える化って有効だよね」


ひな形を作成する

樹里「ではさっそく作ってみるが……絵子がちゃんと理解出来るよう、段階を追って作っていくぞ。今日の目標は、手動でのページ切り替えだ」

絵子「お気づかいありがとう」

樹里「さて、アプリ名だが……絵子、アプリ名はslideshowLeg-Fetishismのどっちがいい?」

絵子「ぜひslideshowでお願いします」

樹里「そうか。では」

ng new slideshow --routing

絵子「ひな形を自動で作ってくれるコマンドだね……でも樹里、最後の--routingって何?」

樹里「このオプションを追加すると、ルーティング用のモジュールも同時に作ってくれる。そして、そのモジュールこそが重要であり、今回の主役だ」

絵子「へー。……で、ルーティングって何?毛づくろいだっけ?」

樹里「そりゃグルーミングだ。全然合ってないぞ……ざっくり言うと、『こういうURLの時はこのコンテンツを表示させるよ』というルールを定義することだ。『/page1』というURLならpage1の内容を表示する、と言った具合に」

絵子「あ、それならわかるよ。それを早く言ってよ」

樹里「ただ、ルーティングはAngularでは基本中の基本機能なので、優良な解説記事はここQiitaを始めいくらでも存在する。詳しいことはそちらを参照するように。今回は、あくまで次回以降の記事の準備だと思ってほしい」

絵子「筋道立てて説明しないとね。ルートだけにね」


コンポーネントを追加する

樹里「では、ひな形が出来上がったところで、表示させるWebページのコンポーネントも追加しておこう。これもコマンドで簡単に出来る」

ng g component page1

ng g component page2
ng g component page3

樹里「gはgenerateの略で、生成するという意味だ。このコマンドを打つと、page1などのディレクトリが作られ、中に必要なファイルが生成される。とりあえず3ページ分作った」

絵子「おー、htmlとかcssとか色々できてる」

樹里「ファイルの生成は以上だ。次は、ひな形を修正していくぞ」


ルーティング用モジュールを修正する

樹里「それでは今回の主役、ルーティング用モジュールを修正しよう。app-routing.module.tsを開いて次のように書き換える」


app-routing.module.ts

import { NgModule } from '@angular/core';

import { Routes, RouterModule } from '@angular/router';
/* ↓(1) コンポーネントのインポート */
import { Page1Component } from './page1/page1.component';
import { Page2Component } from './page2/page2.component';
import { Page3Component } from './page3/page3.component';
/* ↑ */

const routes: Routes = [
/*
{
path: '',
children: []
}
*/

/* ↓(2) ルーティングの設定 */
{
path: 'page1',
component: Page1Component,
},
{
path: 'page2',
component: Page2Component,
},
{
path: 'page3',
component: Page3Component
}
/* ↑ */
];

@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }



(1)コンポーネントのインポート

樹里「さっき作った3つのコンポーネントを読み込んでいるだけだ」

絵子「あなたの出番ですよー、って教えてあげているわけだね」


(2)ルーティングの設定

樹里「ここでルーティングを設定してるわけだが」

絵子「思ってたよりシンプルだね。しかも、何を言わんとしてるのか何となくわかる。つまり、『page1』というURLにアクセスしたら『Page1Component』を表示させなさい、っていう風に指定してるんだよね?」

樹里「その通り。ただ、従来のWebページとは違い、URLの遷移によってページ全体が書き換わるわけではない。書き換わるのは、あくまでページの一部だけだ」

絵子「ふーん」


メインコンポーネントを修正する

樹里「では、メインのコンポーネントであるapp.component.tsを見てみよう」


app.component.ts

import { Component } from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
}


絵子「……特に変わったところはなさそうだけど」

樹里「そう。このファイルは、今回は修正するところはない。その代わり、HTMLのテンプレートを次のように書き換える」


app.component.html

<p>

<a routerLink="/page1">page1</a>
<a routerLink="/page2">page2</a>
<a routerLink="/page3">page3</a>
</p>
<p>この下の部分が切り替わるよ!</p>
<router-outlet></router-outlet>

樹里「一番下の<router-outlet></router-outlet>の部分が、ルーティングによって書き換えられる部分だ。逆に言うと、それ以外の部分は一切変化しない」

絵子「なるほど」

樹里「で、リンク先に遷移するためには見慣れた<a>要素を使うのだが、hrefならぬrouterLinkディレクティブというものを用いる」

絵子「なるほど」


メインモジュールを確認する

樹里「では最後に、メインのモジュールであるapp.module.tsを見てみよう


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';
import { Page1Component } from './page1/page1.component';
import { Page2Component } from './page2/page2.component';
import { Page3Component } from './page3/page3.component';

@NgModule({
declarations: [
AppComponent,
Page1Component,
Page2Component,
Page3Component
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }


絵子「あ、Page1Componentとかがいつの間にか追加されてる」

樹里「そう、ng gコマンドでコンポーネントを追加すると、app.module.tsにも自動で追加してくれるのだ」

絵子「気が効くよねー」

樹里「なので、このモジュールも特に書き換えるところはない」


動作確認

樹里「では、さっそく動かしてみよう」

ng s

絵子「コマンド短っ!」

樹里「sserveの略だ。これだけでサーバーが起動する。では。さっそく http://localhost:4200/ にアクセスしよう」

絵子「リンクが3つ並んでるね。クリックすると……おー、『page1 works!』だって」

樹里「それはpage1.component.htmlの内容だな。他のリンクをクリックすると、当然他のページが表示される」

絵子「うんうん、ちゃんと切り替わってる」

樹里「アドレスバーを見ると、 http://localhost:4200/page1 と言うように、URLも切り替わってるのがわかるだろう。アドレスバーに直接URLを入力しても同じ結果になるぞ」

絵子「本当だ」

樹里「このように、『URLに応じて表示するコンポーネントを切り替える』というのは、Angularを使う上で非常に重要な機能なので、ぜひ覚えてほしい」

絵子「はーい」


次回予告

次回は、タイマーによるページの自動遷移について解説します。