[英]Angular: How to deal with shared data between components
例如,我有一個包含余額字段的帳戶信息(我是從服務器獲取的):
export class Account {
constructor(
// ...
public balance: number
) {
}
}
我也有兩個需要該字段的組件。 實際上,問題是:如何在組件中檢索此帳戶?
我有一些假設:
#1
獲取每個組件中的帳戶信息:
// First Component
this.accountService.get().subscribe(...);
// Second Component
this.accountService.get().subscribe(...);
這是最糟糕的解決方案,因為我向服務器發送了兩個請求。
#2
在AppComponent中獲取帳戶信息,然后將其作為輸入傳遞給子級。
這更接近事實,但是如何將這些數據傳遞到路由器插座?
<!-- Is this even possible? -->
<router-outlet [account]="account"></router-outlet>
#3
使用NgRx。 也許是最好的解決方案。 問題是我不需要NgRx進行其他操作(就我而言,它會產生比解決的問題更多的問題),因此我不想下載這么大的庫並將其存儲在捆綁包中。
因此,我應該考慮使用NgRx還是可以建議我針對此問題的更好方法?
PS我也有WebSockets給我帶來新的平衡。 我也必須解決這個問題。 看起來像這樣:
this.socket.fromEvent('new_balance').subscribe(...);
請不要僅僅為此而選擇NgRx。 這是人們最常見的錯誤之一。 有“角度”處理方法。
#1
如果您有孩子-組件之間的父級連接。 您可以使用@Input / @Output裝飾器在它們之間進行通信。
export class AccountChild {
@Input() balance: number;
}
然后在父組件(您在其中調用AccountChild的組件)中傳遞余額,如下所示:
<acconut-child [balance]="balance"></account-child>
#2
另一個選擇是從您的API響應中創建一個主題,然后您可以從任何其他組件進行訂閱。
export class AccountService {
public accounts: Subject<any> = new Subject();
constructor(
private http: HttpClient
) { }
fetchAccounts() {
return this.http.get(...).pipe(
map((result) => {
this.accounts.next(result);
}));
}
}
為了調用API並向主題加載數據,請執行以下操作:
this.accountService.fetchAccounts().subscribe();
現在,從需要該信息的組件中訂閱該主題。
this.accountService.accounts.subscribe((res) => console.log(res));
如果您選擇主題和訂閱的方式,那么當您不再使用該組件時,手動取消訂閱就很重要。
ngOnDestroy() {
this.accountService.accounts.unsubscribe();
}
您不需要ngrx來獲得狀態管理的好處... ngrx具有簡單的原理...您訂閱狀態更改並采取可更新該狀態的操作。 數據有一種狀態輸入和一種輸出狀態。 因此,只需應用該原則:
export class AccountService {
private balanceStore = new Subject(); // state store
balance$ = this.balanceStore.asObservable(); // state observable
loadBalance() { // state altering action
this.get().subscribe(this.balanceStore);
}
}
現在ngrx有大量工具可以幫助您管理這種狀態以及所有這些狀態,但是這種模式無論如何都可以起作用。
您可能希望將狀態加載操作放到tap運算符中,並返回可觀察值以在實踐中控制實際訂閱,或者使用BehaviorSubject並使用諸如解析器之類的東西,但是這里的原理或多或少是通用的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.