在服务中使用 FormArray 时的 OnPush 更改检测

问题描述

开发人员,

我有一个存储 FormArray 的服务,它由一个组件附加并由另一个组件查看。即使 FormArray 是不可变的并且被重新分配,视图也没有成功更新。

如果不使用 OnPush 更改检测,或者使用 changeDetectorRef.detectChanges() 强制刷新更改检测,问题就会消失。不过,这两种解决方案都让人感觉很笨拙,我真的不明白为什么它不能正常工作。

问题示例:https://stackblitz.com/edit/angular-9hwgcn?file=src/app/app.component.html添加商品后,购物商品列表未更新)

解决方法

ChangeDetectionStrategy.OnPush 停止自动更改检测,正如您所经历的那样。它的用例主要是输入/输出组件;它告诉他们只有在 @Input 发生变化时才检测变化。

话虽如此,当我查看您的代码时,

  • 您没有 @Input 组件
  • 您的组件没有父/子关系
  • 您正在开展全球业务

然后您停止自动更改检测。在这种情况下,您必须告诉 Angular 有待检测的更改。

所以,不,它不是 hacky,是的,它正在正常工作。

然而,如果您想避免所有这些并希望您的代码更具反应性,您可以使用可观察对象/主题。举个例子:

export class ShoppingListService {
  shoppingListForm: BehaviorSubject<FormArray> = new BehaviorSubject(
    this.fb.array([])
  );
<ng-container *ngIf="shoppingListService.shoppingListForm | async as shoppingListForm">
  <div class="course-item" *ngFor="let shoppingListItem of shoppingListForm.controls">
    <p>{{ shoppingListItem.value | json }}</p>
  </div>
</ng-container>

Stackblitz