狀態管理我預計拆成三個面向來分享:
這三者共同構成了應用程式的「狀態管理系統」:
讓我們先回答 Angular 的狀態管理中的第一個問題:
👉 「資料應該存在哪裡?」
不同的儲存方式,代表了不同的生命週期、共享範圍,以及不同的使用情境。
有些資料只需要在單一頁面存在,有些必須跨元件共享,有些甚至需要在使用者關閉分頁後仍然保留。
本篇文章將依照三大類來介紹常見的資料儲存方式:
export class ProfileComponent {
userName = 'Alice';
}
@Injectable({ providedIn: 'root' })
export class UserService {
currentUser?: User;
}
💡 補充:Service 可以是
@Injectable({ providedIn: 'root' })
export class NotificationService {
private message$ = new BehaviorSubject<string>('Hello');
get messages() {
return this.message$.asObservable();
}
pushMessage(msg: string) {
this.message$.next(msg);
}
}
大多數儲存方式都只保存「資料」,但在某些情境下,使用者需要的是 整個頁面狀態(例如輸入中的表單、滾動位置、已展開的 Tab)。
這時候可以用 RouteReuseStrategy 來快取整個元件實例。
export class CustomReuseStrategy implements RouteReuseStrategy {
private cache = new Map<string, DetachedRouteHandle>();
shouldDetach(route: ActivatedRouteSnapshot): boolean {
return route.routeConfig?.path === 'order';
}
store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
this.cache.set(route.routeConfig!.path!, handle);
}
shouldAttach(route: ActivatedRouteSnapshot): boolean {
return this.cache.has(route.routeConfig!.path!);
}
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
return this.cache.get(route.routeConfig!.path!) || null;
}
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
return future.routeConfig === curr.routeConfig;
}
}
特性 | Route Reuse Strategy |
---|---|
儲存位置 | 瀏覽器記憶體 |
儲存內容 | 元件實例 + DOM + 狀態 |
生命週期 | 路由存在期間 |
容量限制 | 受記憶體限制 |
存取速度 | 非常快(直接記憶體存取) |
適用場景 | 頻繁切換的頁面,保持使用者體驗 |
層面 | 手動 Service 管理 | Route Reuse Strategy |
---|---|---|
程式碼量 | 大量 boilerplate | 幾乎零額外程式碼 |
維護成本 | 每新增狀態都要改 Service | 完全不用改 |
涵蓋範圍 | 只有手動指定的狀態 | 所有狀態 + DOM 狀態 |
出錯機率 | 容易忘記同步某些狀態 | 零出錯(自動處理) |
效能 | 需要手動序列化 / 反序列化 | 直接記憶體存取 |
localStorage.setItem('theme', 'dark');
sessionStorage.setItem('step', '2');
history.pushState({ page: 1, filter: 'active' }, '');
進階持久化技術,可支援大量資料與離線應用,但 不在本系列範圍。
方式 | 儲存內容 | 生命週期 |
---|---|---|
localStorage | 純資料 (字串化 JSON) | 永久保存 |
Service (Scoped/Global) | 純資料(存在於記憶體) | 應用期間(重新整理即消失) |
RxJS Subject | 可訂閱資料流 | 應用期間 |
Route Reuse | 元件實例 + DOM + UI 狀態 | 路由存在期間(直到回收) |
sessionStorage | 純資料 (字串化 JSON) | 分頁存活(關閉即消失) |
Cookie | 純資料(伺服器/前端皆可存取) | 可自訂過期時間 |
history.state | 任意序列化快照 | 瀏覽紀錄存活期間 |
本篇我們回答了「資料應該存在哪裡」這個問題:
👉 下一篇 Day 17:資料流控制 (Data Flow Control),將探討「資料怎麼流動」。