での変更検出の実装方法を見ると、が切り離されていると実行されないようです (ここでも確認されていAsyncPipe
ます)。this._ref.markForCheck()
ChangeDetectorRef
これの動機は、変更検出がいつ発生するかを完全に制御すること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...
}
}