【发布时间】:2020-05-20 02:41:58
【问题描述】:
我一直在使用异步管道进行直接绑定,例如:
component.ts:
uiData$ = this.someService.uiData$;
HTML:
<ng-container *ngIf="uiData$ | async as holdingData">
最近业务逻辑发生了一些变化,我需要对这个管道返回的数据进行一些检查。所以我想这样做:
<ng-container *ngIf="uiData$ | async as holdingData">
{{ storeHoldingData(holdingData) }}
后面的代码:
storeHoldingData(holdingData: HoldingsData): void {
this.holdingData = holdingData;
this.doSomething();
}
这让我改变了检测相关的问题,所以我想知道这是否是一个很好的途径,或者我将跳回传统的 ngOnit() 模式订阅。
我可以从 changeDetection: ChangeDetectionStrategy.OnPush 开始,然后声明 BheaviorSubjects 以传播更改。
新的业务逻辑还为页面上的 Tab 控件中的 Tabs 做出了一些隐藏/显示决策。
在坚持使用异步管道的同时,有没有更好的方法来处理这种变化?
【问题讨论】:
-
将 pipe() 添加到 uiData$ 并使用 map 等运算符根据需要转换数据。然后,您可以继续使用异步管道。此外,您应该避免在模板代码中执行函数,因为它会执行得太频繁。如果你需要执行一些副作用,比如在holdingData上存储值,你可以使用像tap这样的操作符。
-
@AlexanderStaroselsky 我认为点击是创建数据的本地副本的好主意,但是如何\何时创建动作流,我认为 aysn 管道强加 OnPush 策略,因此我仍然需要找出一种将更改传播到 UI 的方法。
-
为什么不能直接显示 uiData$ 的流输出,需要使用运算符进行任何修改?为什么它需要存储在另一个变量上?转换/计算可能发生在 RxJS 运算符中。
-
@AlexanderStaroselsky : uiData$ 是一个示例,它将数据与其他流结合以执行此逻辑,因此 IMO 它需要自己的空间来进行此类计算,而且一些 UI 控件需要显示 \hide基于不那么直接的运营商。
-
嗯,有很多方法可以解决这个问题,但您绝对可以只订阅和操作存储的数据。话虽如此,这就是为什么使用诸如 RxJS Subject 之类的机制来制作服务的原因,它会根据动作/交互发出更新的数据。您也可以考虑使用 ngrx 或类似的商店。
标签: angular rxjs observable reactive-programming behaviorsubject