Angular:如何处理组件之间的共享数据

时间:2019-07-19 15:11:59

标签: angular ngrx

例如,我有一个包含余额字段的帐户信息(我是从服务器上获取的):

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还是可以建议我针对此问题的更好方法?

P.S。我也有WebSockets,给我带来了新的平衡。我也必须解决这个问题。看起来像这样:

this.socket.fromEvent('new_balance').subscribe(...);

2 个答案:

答案 0 :(得分:1)

请不要仅为此目的而使用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();
}

答案 1 :(得分:0)

您不需要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并使用诸如解析器之类的东西,但是这里的原理或多或少是通用的。