例如,我有一个包含余额字段的帐户信息(我是从服务器上获取的):
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(...);
答案 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并使用诸如解析器之类的东西,但是这里的原理或多或少是通用的。