前言 近期專案遇到一個當不是使用公用的component情況下,如何把 component 的資料傳遞到其他 component 中,確保已經有加入到暫存檔中。遇到這問題不用讓chatGpt 詢問答案,只需要執行方向就可以解決問題。
解決方向 
BehaviorSubject : 這個是一個可以讓資料傳遞的方式,可以讓資料傳遞到其他 component 中,也是在創建angular 會產生的 rsjx 套件。 
localstorage : 這個是瀏覽器的暫存檔,可以讓資料傳遞到其他 component 中,但是這個方式會有一個問題,就是當資料量大的時候,會造成瀏覽器的效能問題 (備註 : 預設為5 ~ 10 MB 範圍大小)。 
IndexedDB : 這是 網頁瀏覽器 提供的資料暫緩區,不會遇到資料太大無法存檔的問題 (因為時間問題之後再研究)。 
 
最終解決方案 因為專案時程關係,我會選擇比較能確認可行性的做法執行,BehaviorSubject + localstorage 是我最後選擇的方案。
BehaviorSubject 會因為瀏覽器關閉、重新整理會造成資料消失,因此需要 localstorage 來做資料儲存,這樣就可以確保資料不會消失問題,但是需要定期清除 localstorage 才不會讓暫存爆掉。
 
實作 首先,我們起手專案就簡單創建一個專案,並且創建兩個 component,一個是傳遞資料的 component,一個是接收資料的 component。
1 2 3 4 ng new angular-app ng g @schematics/angular:component @View/PageOne ng g @schematics/angular:component @View/PageTwo ng g @schematics/angular:service @Service/GlobalData 
 
一、設定 app.module.ts 因為我們專案會用到部分 formmodule,所以需要先引入進來。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @NgModule ({  declarations : [     AppComponent ,     PageOneComponent ,     PageTwoComponent    ],   imports : [     BrowserModule ,     AppRoutingModule ,     FormsModule ,   ],   providers : [],   bootstrap : [AppComponent ] }) export  class  AppModule  { }
 
二、設定 app-routing.module.ts 1 2 3 4 5 6 const  routes : Routes  = [  { path : 'page-one' , component : PageOneComponent  },   { path : 'page-two' , component : PageTwoComponent  },   { path : '' , redirectTo : '/page-one' , pathMatch : 'full'  },   { path : '**' , redirectTo : '/page-one' , pathMatch : 'full'  } ]; 
 
三、設定 GlobalData 這邊我就用 setData 、 getData 來做資料傳遞,並且在初始化時,會先去 localstorage 中讀取資料,確保資料不會消失。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import  { Injectable  } from  '@angular/core' ;import  { BehaviorSubject  } from  'rxjs' ;@Injectable ({  providedIn : 'root' , }) export  class  GlobalDataService  {  private  dataSubject = new  BehaviorSubject <any >({});   data = this .dataSubject .asObservable ();   constructor ( ) {          const  storedData = localStorage .getItem ('myData' );     if  (storedData) {       this .dataSubject .next (JSON .parse (storedData));     }   }   setData (name : string , value : any  ) {     const  currentData = this .dataSubject .value ;     const  updatedData = { ...currentData, [name]: value };     this .dataSubject .next (updatedData);          localStorage .setItem ('myData' , JSON .stringify (updatedData));   }   getData (name : string  ) {     const  currentData = this .dataSubject .value ;     return  currentData[name] ?? null ;   } } 
 
設定 PageOneComponent、PageTwoComponent 
PageOneComponent 
 
1 2 3 4 5 6 7 8 <div >   <label  for ="" > 測試傳值</label >    <input  type ="text"  [ngModel ]="testValue"  (ngModelChange )="onChangeValue($event)"  >    <div >      <button  type ="button"  [routerLink ]="'/page-two'" > 傳至 page two</button >    </div >  </div > 
 
1 2 3 4 testValue :string  = "" ;onChangeValue (event : any  | null  ) {  this .globalDataService .setData ('testValue' , event); } 
 
PageTwoComponent 
 
1 2 3 4 5 6 7 8 <p > page-two works!</p > <div >   {{testValue}}} </div > <div >   <button  type ="button"  [routerLink ]="'/page-one'" > 傳至 page one</button >  </div > 
 
1 2 3 4 5 6 7 8 testValue :string  = "" ;constructor (  private  globalDataService : GlobalDataService   ) { }ngOnInit (): void  {  this .testValue  = this .globalDataService .getData ('testValue' ); } 
 
完成以下動作後,可以利用 console.log 來確認資料是否有傳遞成功,功能相當簡單但是需要記得要將多餘資料清掉。 若使用 IndexedDB 或者情況就會變成更單純一點,之後有機會再來研究 ~。
更新 2023/11/22 以上敘述的方式,要當作為暫存資料的方式,需要被動存取簡易建議另外處理(例如 : 整理時彈出視窗),否則暫存意義就會不存在。
 
範例程式碼 
Github