todolist小案例 "該案例的模板文件下載地址" 走外國伺服器, ̄□ ̄|| app.module.ts 核心組件app.component.ts 發現這倆不是同一類文件,哈哈哈,٩(๑ ◡ !t.done) } else if (this.visibility === 'completed') ...
todolist小案例
走外國伺服器, ̄□ ̄||
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
核心組件app.component.ts
發現這倆不是同一類文件,哈哈哈,٩(๑>◡<๑)۶
import { Component } from '@angular/core';
const todos = [
{
id: 1,
title: '吃飯',
done: true
},
{
id: 2,
title: '唱歌',
done: false
},
{
id: 3,
title: '寫代碼',
done: true
}
]
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
public todos: {
id: number,
title: string,
done: boolean
}[] = JSON.parse(window.localStorage.getItem('todos') || '[]')
public visibility: string = 'all'
public currentEditing: {
id: number,
title: string,
done: boolean
} = null
// 該函數是一個特殊的 Angular 生命周期鉤子函數
// 它會在 Angular 應用初始化的時候執行一次
ngOnInit () {
// 初始化的時候手動調用一次
this.hashchangeHandler()
// 註意:這裡要 bind this綁定
window.onhashchange = this.hashchangeHandler.bind(this)
}
// 當 Angular 組件數據發生改變的時候,ngDoCheck 鉤子函數會被觸發
// 我們要做的就是在這個鉤子函數中去持久化存儲我們的 todos 數據
ngDoCheck() {
window.localStorage.setItem('todos', JSON.stringify(this.todos))
}
get filterTodos () {
if (this.visibility === 'all') {
return this.todos
} else if (this.visibility === 'active') {
return this.todos.filter(t => !t.done)
} else if (this.visibility === 'completed') {
return this.todos.filter(t => t.done)
}
}
// 實現導航切換數據過濾的功能
// 1. 提供一個屬性,該屬性會根據當前點擊的鏈接返回過濾之後的數據
// filterTodos
// 2. 提供一個屬性,用來存儲當前點擊的鏈接標識
// visibility 字元串
// all、active、completed
// 3. 為鏈接添加點擊事件,當點擊導航鏈接的時候,改變
//
addTodo (e): void {
const titleText = e.target.value
if (!titleText.length) {
return
}
const last = this.todos[this.todos.length - 1]
this.todos.push({
id: last ? last.id + 1: 1,
title: titleText,
done: false
})
// 清除文本框
e.target.value = ''
}
get toggleAll () {
return this.todos.every(t => t.done)
}
set toggleAll (val: boolean) {
this.todos.forEach(t => t.done = val)
}
removeTodo (index: number): void {
this.todos.splice(index, 1)
}
saveEdit (todo, e) {
// 保存編輯
todo.title = e.target.value
// 去除編輯樣式
this.currentEditing = null
}
handleEditKeyUp (e) {
const {keyCode, target} = e
if (keyCode === 27) {
// 取消編輯
// 同時把文本框的值恢復為原來的值
target.value = this.currentEditing.title
this.currentEditing = null
}
}
get remaningCount () {
return this.todos.filter(t => !t.done).length
}
hashchangeHandler () {
// 當用戶點擊了錨點的時候,我們需要獲取當前的錨點標識
// 然後動態的將根組件中的 visibility 設置為當前點擊的錨點標識
const hash = window.location.hash.substr(1)
switch (hash) {
case '/':
this.visibility = 'all'
break;
case '/active':
this.visibility = 'active'
break;
case '/completed':
this.visibility = 'completed'
break;
}
}
// 清除所有已完成任務項
clearAllDone () {
this.todos = this.todos.filter(t => !t.done)
}
}
模板app.component.html
<section class="todoapp">
<header class="header">
<h1>todos</h1>
<input
class="new-todo"
placeholder="What needs to be done?"
autofocus
(keyup.enter)="addTodo($event)">
</header>
<ng-template [ngIf]="todos.length">
<!-- This section should be hidden by default and shown when there are todos -->
<section class="main">
<input
id="toggle-all"
class="toggle-all"
type="checkbox"
(change)="toggleAll = $event.target.checked"
[checked]="toggleAll">
<label for="toggle-all">Mark all as complete</label>
<ul class="todo-list">
<!-- These are here just to show the structure of the list items -->
<!-- List items should get the class `editing` when editing and `completed` when marked as completed -->
<!--
li 是每一個任務項
每個任務項有三種狀態:
正常狀態 沒有樣式
完成狀態 completed
編輯狀態 editing
-->
<li
*ngFor="let todo of filterTodos; let i = index;"
[ngClass]="{
completed: todo.done,
editing: currentEditing === todo
}">
<div class="view">
<input
class="toggle"
type="checkbox"
[(ngModel)]="todo.done">
<label (dblclick)="currentEditing = todo">{{ todo.title }}</label>
<button
class="destroy"
(click)="removeTodo(i)"></button>
</div>
<input
class="edit"
[value]="todo.title"
(keyup)="handleEditKeyUp($event)"
(keyup.enter)="saveEdit(todo, $event)"
(blur)="saveEdit(todo, $event)">
</li>
</ul>
</section>
<!-- This footer should hidden by default and shown when there are todos -->
<footer class="footer">
<!-- This should be `0 items left` by default -->
<span class="todo-count"><strong>{{ remaningCount }}</strong> item left</span>
<!-- Remove this if you don't implement routing -->
<ul class="filters">
<li>
<a [ngClass]="{
selected: visibility === 'all'
}" href="#/">All</a>
</li>
<li>
<a [ngClass]="{
selected: visibility === 'active'
}" href="#/active">Active</a>
</li>
<li>
<a [ngClass]="{
selected: visibility === 'completed'
}" href="#/completed">Completed</a>
</li>
</ul>
<!-- Hidden if no completed items are left ↓ -->
<button
(click)="clearAllDone()"
class="clear-completed">Clear completed</button>
</footer>
</ng-template>
</section>
<footer class="info">
<p>Double-click to edit a todo</p>
<!-- Remove the below line ↓ -->
<p>Template by <a href="http://sindresorhus.com">Sindre Sorhus</a></p>
<!-- Change this out with your name and url ↓ -->
<p>Created by <a href="http://todomvc.com">you</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>