Observable 基礎與初始化
Observable 是什麼?
想像你在追蹤快遞包裹:
你可以隨時查看包裹的狀態
狀態會不斷更新(運送中、已送達等)
你可以隨時取消追蹤
在 Angular 中,Observable 就像這個追蹤系統:
// 宣告一個 Observable
location$: Observable<Location[]>; // 慣例:Observable 變數名稱後面加 $
Observable 的初始化方式
1. 直接從服務獲取(最常用)
export class SearchComponent {
// 直接賦值服務方法返回的 Observable
location$ = this.masterService.getLocations();
constructor(private masterService: MasterService) {}
}
2. 明確宣告型別並初始化
export class SearchComponent {
// 方法 1:使用 undefined
location$: Observable<Location[]> | undefined;
// 方法 2:使用 new Observable()
location$: Observable<Location[]> = new Observable<Location[]>();
}
在服務中建立 Observable
@Injectable({
providedIn: 'root'
})
export class LocationService {
constructor(private http: HttpClient) {}
// 返回位置列表的 Observable
getLocations(): Observable<Location[]> {
return this.http.get<Location[]>('/api/locations');
}
}
為什麼要用陣列型別?
// Location[] 表示「位置陣列」
location$: Observable<Location[]>
// 因為 API 通常返回一個列表:
[
{ id: 1, name: "台北", code: "TPE" },
{ id: 2, name: "台中", code: "TCH" },
{ id: 3, name: "高雄", code: "KHH" }
]
在模板中使用 Observable
<!-- 使用 async pipe 訂閱 Observable -->
@for (location of location$ | async; track location.id) {
<div>{{ location.name }}</div>
}
常見使用場景
1. HTTP 請求
// 服務中
getLocations(): Observable<Location[]> {
return this.http.get<Location[]>('/api/locations');
}
// 組件中
locations$ = this.locationService.getLocations();
2. 表單值變更監聽
// 監聽表單變更
searchForm = new FormControl('');
searchResults$ = this.searchForm.valueChanges.pipe(
debounceTime(300),
switchMap(term => this.search(term))
);
3. 數據更新
private locationSubject = new BehaviorSubject<Location[]>([]);
locations$ = this.locationSubject.asObservable();
updateLocations(newLocations: Location[]) {
this.locationSubject.next(newLocations);
}
注意事項
記得使用 async pipe 或取消訂閱
// 不好的做法:可能造成記憶體洩漏
this.location$.subscribe(data => {
this.locations = data;
});
// 好的做法:使用 async pipe
<div *ngFor="let location of location$ | async">
型別定義要清楚
// 不好的做法
location$: Observable<any>;
// 好的做法
location$: Observable<Location[]>;
初始值的考慮
// 如果不確定是否有值,可以使用 undefined
location$: Observable<Location[]> | undefined;
// 如果確定會有值,直接賦值
location$ = this.locationService.getLocations();
小結
Observable 是處理異步數據的強大工具
命名慣例使用 $ 結尾
善用 async pipe 自動處理訂閱
記得定義明確的型別
選擇合適的初始化方式
Last updated