我正在尝试尽可能多地使用异步管道,因为我听说这是最佳实践,因为它可以为您管理可观察的订阅。
我的应用程序的非常简化的版本如下所示:
export class OrderDetailComponent implements OnInit {
order$: Observable<Order>;
lineItems$: Observable<LineItem>;
constructor(
private orderService: OrderService,
private lineItemService: LineItemService
) {}
ngOnInit() {
this.order$ = this.getOrders();
this.lineItems$ = this.getLineItems();
}
private getOrders(): Observable<Order> {}
private getLineItems: Observable<LineItem[]>;
}
然后模板看起来像这样:
<div *ngIf="order$ | async; let order">
Order#: {{order.ID}}
Line Items
<div *ngIf="lineItems$ | async; let lineItems">
<div *ngFor="let li of lineItems">
<app-lineitem-card [lineItem]="li"></app-lineitem-card>
</div>
</div>
Order Summary:
Total: {{order.Total}}
</div>
显然,这是经过简化的,但要点是页面上几乎所有地方都需要顺序,因此我在最外面的div上使用了异步管道。这在第一页加载时效果很好,但是我遇到的情况是我更新了一部分订单,而该订单实际上只影响页面的一小部分,例如order.Total。我知道我可以执行以下操作来更新订单:
this.order$ = this.getOrder()
但这会导致所有组件重新初始化(由于ngIf)。处理这种情况的正确方法是什么?
答案 0 :(得分:2)
阅读:
但是这次,我们明确地告诉Angular我们的组件仅取决于其输入,并且它们都是不可变的。然后,Angular假定MovieComponent没有改变,并将跳过对该组件的检查。
解释尽可能少的单词:更改检测策略会影响angular决定何时重新渲染组件的方式。使用默认时,它将遍历所有属性以检查更改(以及其他触发器)。使用 OnPush 时,更改检测将仅对输入参数进行相等性检查,以确定是否需要重新呈现。因此,数据中的任何更改都只会在对象实例发生更改时反映出来。
您需要考虑不变性,并有意识地选择何时克隆对象以触发更新。在处理大量数据的复杂页面上,这确实会对性能产生重大影响。
使用ngrx / store或ngxs可以帮助遵循这种模式。
答案 1 :(得分:0)
说到API方面,为什么没有嵌套 Observable
:
class Order {
idThatWillNeverChange: FooType;
someChangingProperty$: Observable<SomeType>;
}
并非没有可能。您如何精确地保持已加载的Order
“有效”(正在接收更新)是另一回事。