3. Todo新規作成を作成する

July 18, 2016 · View on GitHub

Todo新規作成機能を作成します。手順は以下の通りです。

  • TodoServiceクラスに作成機能を追加する
  • Todo新規作成部品(TodoHeaderComponent)を作成する
  • AppComponentにTodoHeaderComponentを追加する

TodoServiceクラスに作成機能を追加する

Todoを実際に登録する機能をServiceクラスに追加します。今回はlocalStorageに保存します。

まず、localStorageのKeyを定義した後にadd()を変更します。localStorageへの値の保存部分は、後の処理でもたびたび利用するためsave()として定義しておきます。

:pencil2: app/services/todo.service.ts

import {Injectable} from "@angular/core";
import {Todo} from "../models/todo.model";

+ const STORAGE_KEY = 'angular2-todo';

@Injectable()
export class TodoService {

+  todos:Todo[] = [];

  constructor() {}

-  add():void {
+  add(title:string):void {
+    let newTodo = new Todo(
+      Math.floor(Math.random() * 100000), // ランダムにIDを発番する
+      title,
+      false
+    );
+    this.todos.push(newTodo);
+    this.save();
  }

  remove():void {}
  toggleComplate():void {}

+  private save():void {
+    console.log('saving : ', this.todos);
+    localStorage.setItem(STORAGE_KEY, JSON.stringify(this.todos));
+  }
}

Todo新規作成部品(TodoHeaderComponent)を作成する

まず、画面上にTodo作成エリアを表示するためにComponentを作成します。Angualr2のComponentは主にTemplateとComponentの2つから構成されます。

:pencil2: app/components/header/header.html

<header class="well">
  <h1>Todos</h1>
  <form class="form-inline">
    <div class="form-group">
      <label>新しいTodo:</label>
      <input class="form-control" name="title" [(ngModel)]="title">
    </div>
    <button class="btn btn-primary" (click)="addTodo()">追加</button>
  </form>
</header>
  • [(ngModel)]は、Component側のtitleとの間で値の変更があった場合に、双方向で変更内容を共有します(two-way binding)。
  • (click)は、Clickイベントハンドラです。ボタンがクリックされるとComponent側のaddTodoを呼び出します。

:sparkles: その他のテンプレートシンタックスについては、公式のAngular Cheat Sheetが一番良くまとまっています。

:pencil2: app/components/header/header.component.ts

import {Component} from '@angular/core';
import {TodoService} from '../../services/todo.service';

@Component({
  selector: 'todo-header',
  templateUrl: 'app/components/header/header.html'
})
export class TodoHeaderComponent {

  title:string;

  constructor(private service:TodoService) {}

  addTodo() {
    if (this.title.trim().length) {
      this.service.add(this.title);
      this.title = null;
    }
  }

}

:sparkles: Componentクラス内のクラス変数とコンストラクタの引数で渡されたServiceは、Componentクラス内でthisを使って参照できます。

:sparkles: Componentのテンプレートを指定する方法は、templateUrlで外部ファイルを指定する方法と、templateで直接Component内にテンプレートを記述する方法があります。

AppComponentにTodoHeaderComponentを追加する

(⚠️:warning: app.htmlapp.component.tsの中身は一度全てクリアした上で進めてください。:warning::warning:)

先ほど作成したTodoHeaderComponentは、AppComponentに追加することで画面上に表示することができます。

:pencil2: app/app.component.ts

import {Component} from '@angular/core';
import {TodoHeaderComponent} from './header/header.component';
import {TodoService} from '../services/todo.service';

@Component({
  selector: 'my-app',
  templateUrl: 'app/components/app.html',
  providers: [TodoService],
  directives: [TodoHeaderComponent]
})
export class AppComponent {
  constructor() {}
}

TodoHeaderComponentとTodoServiceは、それぞれprovidersdirectivesに設定することで初めてComponent上で利用することができます。

続いて、TodoHeaderComponentを画面上に配置します。

:pencil2: app/app.html

<section class="container">
  <todo-header></todo-header>
</section>

<footer class="container">
  Created by YOUR_NAME
</footer>

todo-headerはTodoHeaderComponentのselectorに設定した名前です。このように、Angular2では作成したComponentをあらゆるところで簡単に配置することができます。

以上でこの章は終了です。

画面上にTodo作成エリアが表示されて、Todoが正しくlocalStorageに保存されていれば次に進んでください。