Angular 新舊控制流語法比較(ngFor / @for)

一、傳統的 *ngFor 語法

基本用法

<!-- 基本遍歷 -->
<div *ngFor="let item of items">
  {{ item.name }}
</div>

<!-- 帶索引的遍歷 -->
<div *ngFor="let item of items; let i = index">
  {{ i + 1 }}. {{ item.name }}
</div>

包含其他條件

<!-- 結合 *ngIf -->
<div *ngFor="let item of items">
  <div *ngIf="item.active">
    {{ item.name }}
  </div>
</div>

二、新的 @for 控制流語法

基本用法

<!-- 基本遍歷 -->
@for (item of items; track item.id) {
  <div>{{ item.name }}</div>
}

<!-- 使用索引 -->
@for (item of items; track item.id; let i = $index) {
  <div>{{ i + 1 }}. {{ item.name }}</div>
}

空值處理

@for (item of items; track item.id) {
  <div>{{ item.name }}</div>
} @empty {
  <div>No items found</div>
}

三、實際應用範例

1. 使用 Observable 數據

<!-- 舊語法 -->
<div *ngFor="let location of locations$ | async">
  {{ location.name }}
</div>

<!-- 新語法 -->
@for (location of locations$ | async; track location.id) {
  <div>{{ location.name }}</div>
} @empty {
  <div>No locations available</div>
}

2. Select 下拉選單

<!-- 舊語法 -->
<select>
  <option value="">Select location</option>
  <option *ngFor="let location of locations" [value]="location.id">
    {{ location.name }}
  </option>
</select>

<!-- 新語法 -->
<select>
  <option value="">Select location</option>
  @for (location of locations; track location.id) {
    <option [value]="location.id">{{ location.name }}</option>
  }
</select>

四、重要差異

1. track 參數

  • 舊語法:不需要明確指定追蹤鍵

  • 新語法:必須指定 track 表達式

<!-- 使用對象屬性 -->
@for (item of items; track item.id)

<!-- 使用索引 -->
@for (item of items; track $index)

2. 空值處理

  • 舊語法:需要額外的 *ngIf

  • 新語法:內建 @empty 區塊

<!-- 舊語法 -->
<div *ngIf="items.length === 0">No items found</div>
<div *ngFor="let item of items">{{ item.name }}</div>

<!-- 新語法 -->
@for (item of items; track item.id) {
  <div>{{ item.name }}</div>
} @empty {
  <div>No items found</div>
}

五、效能考量

新語法優勢

  1. 更好的變更檢測

  2. 更清晰的追蹤機制

  3. 減少 DOM 操作

使用建議

  1. 新項目建議使用新語法

  2. 舊項目可以逐步遷移

  3. 必須指定 track 表達式,推薦使用唯一識別符

六、注意事項

  1. track 表達式的選擇

<!-- 好的做法:使用唯一識別符 -->
@for (item of items; track item.id)

<!-- 不推薦:使用可能重複的值 -->
@for (item of items; track item.name)
  1. 複雜邏輯處理

<!-- 多條件判斷 -->
@for (item of items; track item.id) {
  @if (item.active) {
    <div>{{ item.name }}</div>
  }
}

Last updated