Todoのクローズと削除機能を作成します。手順は以下の通りです。
- ServiceクラスにTodoの完了と削除機能を作成する。
- Todo表示部品(TodoContentComponent)に完了と削除機能を追加する。
- Todo完了時スタイルを変更する。
早速、ServiceクラスにTodoの完了と削除機能を作成しましょう。Todoの完了は、Todoの isCompleted=false
にすることで表現します。
✏️ app/services/todo.service.ts
@Injectable()
export class TodoService {
// ... 省略
- remove():void {
+ remove(todo:Todo):void {
+ const index = this.todos.indexOf(todo);
+ this.todos.splice(index, 1);
+ this.save();
}
- toggleComplate():void {
+ toggleComplate(todo:Todo):void {
+ this.todos.filter(t => t.id === todo.id)
+ .map(t => t.isCompleted = !t.isCompleted);
+ this.save();
}
// ... 省略
}
Todo表示部品(TodoContentComponent)に次の操作部品を追加します。
- Todoの完了:チェックボックスで操作する
- Todoの削除:「削除」ボタンで操作する
✏️ app/components/content/content.component.ts
import {Component, Input} from '@angular/core';
import {Todo} from "../../models/todo.model";
+ import {TodoService} from "../../services/todo.service";
@Component({
selector: 'todo-content',
templateUrl: 'app/components/content/content.html'
})
export class TodoContentComponent {
@Input()
todos:Todo[];
- constructor() {}
+ constructor(private service:TodoService) {}
+
+ toggleComplate(todo:Todo) {
+ this.service.toggleComplate(todo);
+ }
+
+ deleteTodo(todo:Todo) {
+ this.service.remove(todo);
+ }
}
✏️ app/components/content/content.html diff
<ul class="list-group">
<li class="list-group-item" *ngFor="let todo of todos; let i = index">
<div class="row">
<div class="col-xs-10">
+ <label>
+ <input type="checkbox"
+ (click)="toggleComplate(todo)"
+ [checked]="todo.isCompleted">
+ </label>
<span>
{{i + 1}}. {{todo.title}}
</span>
</div>
<div class="col-xs-2">
+ <button class="btn btn-link" (click)="deleteTodo(todo)">削除</button>
</div>
</div>
</li>
<li class="list-group-item text-danger" *ngIf="!todos.length">Todoがありません。</li>
</ul>
[checked]
は、右のtodo.isCompleted
の結果がtrue
になった場合、チェックをつけます。
最後に、Todo完了時にTodoに取り消し線を追加するようにスタイルを微調整します。TodoContentComponentにカスタムスタイル用のCSSを追加して、Todoの完了状態に応じてスタイルを変更します。
✏️ app/components/content/content.css
.complate {
text-decoration: line-through;
}
作成したスタイルをComponent側で利用できるようにします。
✏️ app/components/content/content.component.ts
import {Component, Input} from '@angular/core';
import {Todo} from "../../models/todo.model";
import {TodoService} from "../../services/todo.service";
@Component({
selector: 'todo-content',
- templateUrl: 'app/components/content/content.html'
+ templateUrl: 'app/components/content/content.html',
+ styleUrls: ['app/components/content/content.css']
})
export class TodoContentComponent {
// ... 省略
//
}
✨ ComponentのCSSを指定する方法は、
styleUrls
で外部ファイルを指定する方法と、styles
で直接Component内にCSSを記述する方法があります。
✨
styleUrls
,styles
で指定されたスタイルは、Component内で閉じた形で展開されているため、外部のスタイルに影響しません。
✏️ app/components/content/content.html
<ul class="list-group">
<li class="list-group-item" *ngFor="let todo of todos; let i = index">
<div class="row">
<div class="col-xs-10">
<label class="">
<input type="checkbox"
(click)="toggleComplate(todo)"
[checked]="todo.isCompleted">
</label>
- <span>
+ <span [class.complate]="todo.isCompleted">
{{i + 1}}. {{todo.title}}
</span>
</div>
<div class="col-xs-2">
<button class="btn btn-link" (click)="deleteTodo(todo)">削除</button>
</div>
</div>
</li>
<li class="list-group-item text-danger" *ngIf="!todos.length">Todoがありません。</li>
</ul>
[class.complate]
は、Anuglar1のng-class
と等価です。
以上でTodoの作成はすべて終了です。 🎉🎉🎉