angular - 当 ChangeDetectorRef 分离时更新 AsyncPipe

标签 angular rxjs angular2-changedetection

通过查看 AsyncPipe 中的 the way change detection is implemented,如果 ChangeDetectorRef 分离(正如在 here 中也确认的那样。

这样做的动机是完全控制何时发生变化检测(通过专门使用 Observable - 类似于 MVVM 模式)。我正在编写一个对性能非常敏感的代码,我可以完全控制输入,但使用 ChangeDetectionStrategy.OnPush 不仅会针对输入更改触发更改检测,还会控制事件触发(如点击事件),这会降低性能通过在每次单击时重新运行不需要的更改检测扫描来大大提高性能。

所以我选择完全分离 ChangeDetectorRef 但现在 AsyncPipe 停止工作。

这是 AsyncPipe 的预期行为吗?如果是这样,有没有办法解决这个问题?或者,一种方法可以让 ChangeDetectorStrategy.OnPush 在控制事件触发时不触发?


编辑:
这是一个人为的例子来说明我的意思:

@Component({
  template: `
  <button (click)="incrementEvent.next()">Increment</button>
  <button (click)="decrementEvent.next()">Decrement</button>
  <h2>Counter: {{ counterObservable | async }}</h2>
  <!-- This should only run once but it runs on every click instead -->
  <h2>Number of atoms in universe: {{ getNumberOfAtomsInUniverse() }}</h2>
`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class CounterComponent {
  incrementEvent = new Subject<void>();
  decrementEvent = new Subject<void>();

  counterObservable: Observable<number>;

  constructor() {
    this.counterObservable = Observable.merge(
      this.incrementEvent.map(() => 1),
      this.decrementEvent.map(() => -1)
    )
      .startWith(0)
      .pairwise()
      .map(tup => tup[0] + tup[1])
  }

  getNumberOfAtomsInUniverse() {
    // very expensive operation...
  }
}

最佳答案

这里有一个很好的讨论:https://github.com/angular/angular/issues/12356

...calling detach() on ChangeDetectorRef means: don't run change detection (check bindings, process child components etc.) in a template of a given component. In practice this means that data might change but the affected bindings will not be re-evaluated (this is what change detection does, after all...).

所以在示例中 {{ counterObservable |异步}}。如果您分离更改检测器,这将永远不会评估绑定(bind)并且异步管道永远不会运行。

我想也许我们可以在第一个变化检测周期之后分离,所以异步管道已经被消耗,但它仍然不会更新后续的异步事件。目前看来没有办法解决这个问题。

选项是手动运行 detectChanges() 或直接更新 dom。

关于angular - 当 ChangeDetectorRef 分离时更新 AsyncPipe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40098666/

相关文章:

javascript - Angular2 zone.run() 与 ChangeDetectorRef.detectChanges()

重新绘制 dom 的 Angular 变化检测过程

angular - 双向 Angular 绑定(bind)中的 ExpressionChangedAfterItHasBeenCheckedError

firebase - 无法订阅combineLatest的结果

Angular 2+,异步测试和 setTimeout

javascript - Angular 与 TypeScript - 如何在可观察回调中处理业务逻辑?

mysql - Angular 4 与 Nodejs 和 Mysql 连接

angular - 在订阅中捕获错误是不可能的吗?

javascript - 在 RxJS 中,如何在没有主题的情况下直接链接 pub 子系统中的生产者和消费者?

Angular ngFor.如何有条件地显示标题?