Week 08 · Day 04 — 元件結合狀態與 async pipe

學習目標

  • 在元件訂閱 StateService
  • async pipe 自動訂閱/退訂
  • 避免手動管理的記憶體洩漏

重點

元件讀取狀態

@Component({ ... })
export class ListComponent implements OnInit {
  todos$?: Observable<Todo[]>;

  constructor(private state: StateService) {}

  ngOnInit(): void {
    this.todos$ = this.state.getState()
      .pipe(map(s => s.todos));
  }
}
- 保留 Observable($)本身,交給模板

async pipe 自動化

<ul>
  <li *ngFor="let t of todos$ | async">{{ t.title }}</li>
</ul>
- | async:自動訂閱,值進來就渲染;元件銷毀自動退訂 - 省去手動 subscribe / unsubscribe

手動訂閱 & 清理(若需)

ngOnInit(): void {
  this.sub = this.state.getState().subscribe(s => this.todos = s.todos);
}
ngOnDestroy(): void {
  this.sub?.unsubscribe();
}

比較 | 方式 | 優點 | |------|------| | async pipe | 自動訂閱/退訂,程式碼少 | | 手動 subscribe | 可在類別內處理值,但要自己清理 |

推薦 - 顯示資料多用 async pipe 最安全

實作

  1. 建立列表元件,用 async pipe 顯示 todos
  2. 透過 state 的 addTodo 加入資料,畫面自動更新
  3. 對照「手動 subscribe」版本,觀察哪個較簡潔

作業

  • async pipe 訂閱狀態
  • 元件銷毀時自動退訂(驗證無記憶體洩漏)
  • 比較 async pipe 與手動 subscribe