Week 11 · Day 05 — 實作:任務 CRUD
學習目標
- 建立任務 API 服務(get / create / update / delete)
- 用 NgRx 管理任務狀態
- 任務列表與編輯頁面
重點
TodoService(CRUD)
@Injectable({ providedIn: 'root' })
export class TodoService {
private api = 'https://api.example.com/tasks';
constructor(private http: HttpClient) {}
getTasks(): Observable<Todo[]> { return this.http.get<Todo[]>(this.api); }
createTask(todo: Todo): Observable<Todo> {
return this.http.post<Todo>(this.api, todo);
}
updateTask(todo: Todo): Observable<Todo> {
return this.http.put<Todo>(`${this.api}/${todo.id}`, todo);
}
deleteTask(id: string): Observable<void> {
return this.http.delete<void>(`${this.api}/${id}`);
}
}
任務 NgRx state
interface TodoState { todos: Todo[]; loading: boolean; error: string | null }
loadTasks / createTask / updateTask / deleteTask 呼叫 API
- 成功後 dispatch *Success 更新 state
- selectors:selectTodos, selectLoading
任務列表頁
todos$ = this.store.select(selectTodos);
loading$ = this.store.select(selectLoading);
ngOnInit(): void { this.store.dispatch(loadTasks()); }
<mat-card *ngFor="let t of todos$ | async; trackBy: trackById">
<mat-checkbox [checked]="t.status === 'done'"
(change)="toggle(t)"></mat-checkbox>
<span>{{ t.title }}</span>
<button mat-icon-button (click)="edit(t)">...</button>
<button mat-icon-button (click)="remove(t)">...</button>
</mat-card>
任務編輯頁 - Reactive 表單(title 必填、description、category、tags) - 送出時 dispatch create 或 update
實作
- 建立 TodoService(CRUD)
- 建立 todo store(services + effects + 更新)
- 任務列表頁(顯示、刪除、完成切換)
- 任務新增/編輯頁(form + submit)
作業
- 完成任務 CRUD 服務與 store
- 列表頁可顯示、完成、刪除任務
- 編輯頁用表單建立/更新任務