Angular最速マスターへの道 第3章

Blog Single

Angularの6.1.0のRC版が出ているようですが見た所大きな変更はなさそうです。何か新しい機能が追加されたりしないものかと期待している毎日です。

本日もAngular最速マスターへの道やっていきましょう。

第3章目次

  • ModuleとRouting応用
  • 親子関係に位置するComponent

ModuleとRouting応用

ルーティングについては第1章で簡単にご紹介しましたが、今回はそれの応用です。
AngularはページごとにComponentを作成していくわけですが、そうしていると/app配下がcomponentのディレクトリで溢れかえってしまいますね。
さらには同じカテゴリごとにディレクトリを分けたいと思うのも自然なことですよね。
そんな時はModuleを作成します!
これまで初期段階であったAppModuleにComponentがまとめられていましたが、それを役割ごとに分割するといった感じですね。
では早速作っていきましょう。

Module作成

ng g module third --routing

今回はルーティングファイルも分割したかったのでオプションで--routingを使っています。
コマンドを実行したら/app配下に新しいディレクトリとその中にModuleが作成されているはずです。

Component作成、ルーティング設定

では、新しいModuleの中にComponentを作成して表示させるところまでしてみましょう。

ng g component third/third-new
// app.routing.ts
const appRoutes: Routes = [
    // 以下を追記
    {
        path: 'third',
        loadChildren: './third/third.module#ThirdModule'
    },
];

新しいルーティングを呼び出すには最初に読み込まれるAppRoutesに追記する必要があります。
上記のようにすると/thirdというパスがきたらThirdModuleのルーティングを呼ぶことができます。

// third-routing.module.ts
import { ThirdNewComponent } from './third-new/third-new.component';
const routes: Routes = [
    {
        path: '',
        children: [
            {
                path: 'new',
                component: ThirdNewComponent
            },
            {
                path: '**',
                redirectTo: 'new'
            }
        ]
    }
];
// 省略

続いて、ThirdModuleのルーティングを設定しますが、パスの設定が少し注意する点です。
/third/newというようなパスを設定しようとする際は、親のパスは空文字にします。
これは、AppRoutesで既に/thirdというパスがきたらThirdModuleを呼ぶように設定したためです。

さて、これでThirdNewComponentが表示されるはずです。

https://mao-miyaji.github.io/afm/third/new

このようにModuleを分割してやればプロジェクトの構成もわかりやすくなりますね。

親子関係に位置するComponent

これまで作ってきたComponentは1ページに1つでしたよね。
ですが第1章で私はこう説明しています。

Componentとは簡潔に言えばページを構成する部品です。

ページを構成する部品。ということは1ページに複数のComponentを呼び出して構成することができるということです。
この場合、Componentの中にComponentを配置するという親子関係が生じます。
では早速その親子関係を作成してみましょう。

ng g component third/parent
ng g component third/child
<!-- third-parent.component.html -->
<app-third-child></app-third-child>

はい、出来ました。これだけです。
実は第1章のComponent作成でも、app.component.htmlに似たような書き方をしましたが、あれも親子関係なんです。
知らないうちに親子関係作っていたんです(笑)

これだけではつまらないので、もっと親子らしくComponent間でやりとりをさせましょう。

Input

まずは親から子に値を渡す方法。
子側にInputというdecorator(修飾子)を設定します。

// third-child.component.ts
export class ThirdChildComponent {
    @Input() text: string = '';

    // 省略
<!-- third-child.component.html -->
<p>親からのテキスト: {{text}}</p>
<!-- third-parent.component.html -->
<app-third-child text="あいうえお"></app-third-child>

子側のプロパティに値をセットすることができます。
この場合は単に文字列を渡しましたが、数字でも配列でもオブジェクトでも渡すことができます。

Output

では今度は子から親に値を渡す方法。
Outputというdecoratorをこちらも子側に設定します。

<!-- third-child.component.html -->
<button (click)="onClick()">ボタンを押してください</button>
// third-child.component.ts
import { Output, EventEmitter } from '@angular/core';

export class ThirdChildComponent {
    @Output() clickBtn: EventEmitter<string> = new EventEmitter();

    public onClick(): void {
        this.clickBtn.emit('ボタンが押されました!');
    }
    // 省略
// third-parent.component.ts
export class ThirdParentComponent {
    public receiveText: string; 
    // 省略
<!-- third-parent.component.html -->
<app-third-child (clickBtn)="receiveText = $event"></app-third-child>
<p>{{receiveText}}</p>

子から親へ渡す場合はプロパティではなくイベントを発行することで渡すことができます。
この場合は子コンポーネント内のボタンを押すとイベントが発火して親で文字列を受け取っています。

文字列を渡すだけならどちらも割と簡単ですね。
HTMLのタグの属性とほぼ動きは同じだと考えれば少しわかりやすいですかね。
さて、デモの方ではちょっと応用させてオブジェクトを渡すものを作ってみました。
DEMOはこちら
親のコードはこちら
子のコードはこちら

まとめ

今回の内容をマスターすることでComponentをあらゆるところで使いまわしたりもできますし、ファイル構成やコードを綺麗にまとめることもできるので便利です。
Angularでプロジェクトを作成する場合は最初から積極的に分割してまとめていくことが理想ですね。

次章予告

  • 共有モジュールの作成
  • Lifecycle Hooks

参考

Angular最速マスターへの道シリーズはGitHubに公開しています。

Posted by Mao Miyaji
千葉にある夢の国を愛して止まない、元「魚のお姉さん」のエンジニア。PHP, TypeScriptメインで、暇さえあれば色々な言語を一かじり。

Other Posts: