上一篇利用 ngIf
指令實作了兩個條件分支的需求。然而,實務上還會遇到有多個條件分支的需求,在這一篇將利用另外一個 Angular 內建的指令 - ngSwitch
來實作下面需求。
為要實作此項需求,先在待辦事項的類別 (task.ts) 加入預估等級、預計與實際完成日期等資訊。
import { TaskState } from "../enum/task-state.enum";
export class Task {
constructor(
public subject: string,
public state: TaskState = TaskState.None
) {}
level?: "XS" | "S" | "M" | "L" | "XL";
expectDate?: Date;
finishedDate?: Date;
}
接著在 app.component.ts 中,設定三筆待辦事項各自資訊。
export class AppComponent implements OnInit {
tasks: Task[] = [];
ngOnInit(): void {}
onLoad(): void {
this.tasks = [
new Task("頁面需要顯示待辦事項主旨"),
new Task("可以設定待辦事項的狀態", TaskState.Doing),
new Task("當待辦事項狀態為已完的事項無法編輯事項", TaskState.Finish),
];
this.tasks[0].level = "XS";
this.tasks[1].level = "S";
this.tasks[1].expectDate = new Date(2020, 10, 1);
this.tasks[2].level = "M";
this.tasks[2].expectDate = new Date(2020, 9, 1);
this.tasks[2].finishedDate = new Date(2020, 9, 1);
}
onClear(): void {
this.tasks = [];
}
}
在 JavaScript 中,Date 物件建構式在指定月份時,是以 0 為啟始,所以上面實作程式第二筆預計完成日期會是 2020/11/1,第三筆則是 2020/10/1。
最後,在 task.component.ts 檔案中加入此三個資訊,並在 task-list.component.html 檔案中將值傳入。
export class TaskComponent implements OnInit, OnChanges {
@Input() subject: string;
@Input() state: TaskState;
@Output() stateChange = new EventEmitter<TaskState>();
@Input() level: "XS" | "S" | "M" | "L" | "XL";
@Input() expectDate: Date;
@Input() finishedDate: Date;
}
<ng-template #list>
<app-task
*ngFor="let task of tasks; let odd = odd"
[class.odd]="odd"
[subject]="task.subject"
[(state)]="task.state"
[level]="task.level"
[expectDate]="task.expectDate"
[finishedDate]="task.finishedDate"
></app-task>
</ng-template>
ngSwitch
實作待辦事項擴增資訊的顯示ngSwitch
是一屬性型指令 (Attribute Directive) 用以繫結要判斷的屬性值,搭配著 *ngSwitchCase
與 *ngSwitchDefault
兩個結構型指令 (Structural Directive)。因此,在 task.component.html 檔案中,利用此指令判斷事項狀態,來決定要顯示的內容。
<div class="card">
<div class="button">
<span>
<button type="button" (click)="onSetTaskState(TaskState.None)">
未完成
</button>
<button type="button" (click)="onSetTaskState(TaskState.Doing)">
進行中
</button>
<button type="button" (click)="onSetTaskState(TaskState.Finish)">
已完成
</button>
</span>
<span [ngSwitch]="state">
<ng-container *ngSwitchCase="TaskState.Doing">
預計完成日期:{{ expectDate }}
</ng-container>
<ng-container *ngSwitchCase="TaskState.Finish">
實際完成日期:{{ finishedDate }}
</ng-container>
<ng-container *ngSwitchDefault>預估等級:{{ level }}</ng-container>
</span>
</div>
</div>
如同 *ngFor
與 *ngIf
相同,Angular 會將上面程式變換成:
<span [ngSwitch]="state">
<ng-template *ngSwitchCase="TaskState.Doing">
<ng-container>預計完成日期:{{ expectDate }}</ng-container>
</ng-template>
<ng-template *ngSwitchCase="TaskState.Finish">
<ng-container>實際完成日期:{{ finishedDate }}</ng-container>
</ng-template>
<ng-template *ngSwitchDefault>
<ng-container>預估等級:{{ level }}</ng-container>
</ng-template>
</span>
這一篇利用 ngSwitch
指令來實作在多判斷條件上的需求,實作程式碼放在 GitHub 中。