通过查看AsyncPipe
中的the way change detection is implemented,如果this._ref.markForCheck()
已分离,则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...
}
}