Our last relevant Blaze Template is the list item - this is a little bit tricky because this template need to interact with the parent Component and get the actual Todo item, and also expose events for the parent Component - so we will use a new Angular 2 features called Input and Output for that.
So let's start with the Component migration this time:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import {Component, Input, Output, EventEmitter} from '@angular/core';import {setCheckedStatus,
updateText,
remove,
} from '../../../imports/api/todos/methods';import {displayError} from '../../../imports/ui/lib/errors';declare let _;@Component({  selector: 'list-item',  templateUrl: '/client/imports/components/list-item.html'})export class ListItemComponent {  @Input("todo") todo: any;  @Input("editing") editing: boolean;  @Output("editChange") editChange = new EventEmitter();  constructor() {  }  toggleEdit(isEdit) {    if (!isEdit || (isEdit && this.editing)) {      this.editChange.emit({editing: isEdit,
        todoId: this.todo._id      });    }  }  remove() {    remove.call({      todoId: this.todo._id,    }, displayError);  }  checkedChange(event) {    setCheckedStatus.call({      todoId: this.todo._id,newCheckedStatus: event.target.checked,
    });  }  updateText(event) {    _.throttle((event) => {      updateText.call({        todoId: this.todo._id,newText: event.target.value,
      }, displayError);    }, 300)(event);  }}We copied the code from the old Blaze Template, and added two Inputs and one Output in the Component declaration:
todo which is the actual todo item.editing which is an indication for the current item that being edited.editChange which is an event we expose to the parent Component that triggered when starting to edit an item in the list.And add the new Component to the NgModule:
8
9
10
11
12
13
14
17
18
19
20
21
22
23
24
import {JoinComponent} from "./components/join.component";import {SigninComponent} from "./components/signin.component";import {FormsModule} from "@angular/forms";import {ListItemComponent} from "./components/list-item.component";@NgModule({    // Components, Pipes, Directive...some lines skipped...ListShowComponent,
ListRedirectorComponent,
JoinComponent,
SigninComponent,
ListItemComponent
],
    // Entry ComponentsentryComponents: [
Now let's migrate the HTML Template of this Component:
1
2
3
4
5
6
7
8
9
10
11
<div class="list-item" [ngClass]="{'editing': editing, 'checked': todo.checked}">    <label class="checkbox">        <input type="checkbox" [checked]="todo.checked" (change)="checkedChange($event)" name="checked">        <span class="checkbox-custom"></span>    </label>    <input type="text" [value]="todo.text" (blur)="toggleEdit(false)" (focus)="toggleEdit(true)" (keyup)="updateText($event)" placeholder="Task name">    <a class="js-delete-item delete-item" (click)="remove()">        <span class="icon-trash"></span>    </a></div>And now we need to use this new Component in the ListShowComponent:
51
52
53
54
55
56
57
    <div class="content-scrollable list-items">        <div *ngIf="todosReady">            <div *ngFor="let todo of todos | async">                <list-item [todo]="todo" [editing]="editingTodo" (editChange)="onTodoItemEditChange($event)"></list-item>            </div>            <div class="wrapper-message" *ngIf="!todos || todos.length == 0">                <div class="title-message">No tasks here</div>And let's implement the actual event handler and use declare the usage of the new Component:
22
23
24
25
26
27
28
101
102
103
104
105
106
107
108
109
110
111
112
    private editing : boolean = false;    private editModel : any;    private newItemModel : string = '';    private editingTodo : number | boolean;    constructor(private currentRoute: ActivatedRoute, private router: Router) {        this.editModel = {...some lines skipped...        }    }    onTodoItemEditChange(event) {        if (event.editing) {            this.editingTodo = event.todoId;        }        else {            this.editingTodo = false;        }    }}And we are done! You can now remove all the files that related to the list item and removed it's import! (we did it in commit #9.6)