iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 11
1
Modern Web

Angular 全集中筆記系列 第 11

第 11 型 - 結構型指令 (Structural Directive) - ngSwitch

  • 分享至 

  • xImage
  •  

上一篇利用 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>

Result

如同 *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 中。


上一篇
第 10 型 - 結構型指令 (Structural Directive) - *ngIf
下一篇
第 12 型 - 管道 (Pipe) - JsonPipe / LowerCasePipe / UpperCasePipe / TitleCasePipe
系列文
Angular 全集中筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言