diff --git a/src/cdk-experimental/scrolling/virtual-scroll-viewport.spec.ts b/src/cdk-experimental/scrolling/virtual-scroll-viewport.spec.ts index 6fe679a20a54..78e1a88c9c07 100644 --- a/src/cdk-experimental/scrolling/virtual-scroll-viewport.spec.ts +++ b/src/cdk-experimental/scrolling/virtual-scroll-viewport.spec.ts @@ -101,9 +101,10 @@ describe('CdkVirtualScrollViewport', () => { it('should set total content size', fakeAsync(() => { finishInit(fixture); + viewport.setTotalContentSize(10000); - fixture.detectChanges(); flush(); + fixture.detectChanges(); expect(viewport.elementRef.nativeElement.scrollHeight).toBe(10000); })); diff --git a/src/cdk-experimental/scrolling/virtual-scroll-viewport.ts b/src/cdk-experimental/scrolling/virtual-scroll-viewport.ts index 670946ca305c..ed0d6669d3b7 100644 --- a/src/cdk-experimental/scrolling/virtual-scroll-viewport.ts +++ b/src/cdk-experimental/scrolling/virtual-scroll-viewport.ts @@ -21,7 +21,7 @@ import { ViewEncapsulation, } from '@angular/core'; import {animationFrameScheduler, fromEvent, Observable, Subject} from 'rxjs'; -import {sampleTime, take, takeUntil} from 'rxjs/operators'; +import {sampleTime, takeUntil} from 'rxjs/operators'; import {CdkVirtualForOf} from './virtual-for-of'; import {VIRTUAL_SCROLL_STRATEGY, VirtualScrollStrategy} from './virtual-scroll-strategy'; @@ -301,11 +301,7 @@ export class CdkVirtualScrollViewport implements OnInit, OnDestroy { if (!this._isChangeDetectionPending) { this._isChangeDetectionPending = true; this._ngZone.runOutsideAngular(() => Promise.resolve().then(() => { - if (this._ngZone.isStable) { - this._doChangeDetection(); - } else { - this._ngZone.onStable.pipe(take(1)).subscribe(() => this._doChangeDetection()); - } + this._doChangeDetection(); })); } } @@ -314,8 +310,10 @@ export class CdkVirtualScrollViewport implements OnInit, OnDestroy { private _doChangeDetection() { this._isChangeDetectionPending = false; - // Apply changes to Angular bindings. - this._ngZone.run(() => this._changeDetectorRef.detectChanges()); + // Apply changes to Angular bindings. Note: We must call `markForCheck` to run change detection + // from the root, since the repeated items are content projected in. Calling `detectChanges` + // instead does not properly check the projected content. + this._ngZone.run(() => this._changeDetectorRef.markForCheck()); // Apply the content transform. The transform can't be set via an Angular binding because // bypassSecurityTrustStyle is banned in Google. However the value is safe, it's composed of // string literals, a variable that can only be 'X' or 'Y', and user input that is run through @@ -330,9 +328,10 @@ export class CdkVirtualScrollViewport implements OnInit, OnDestroy { } } - for (const fn of this._runAfterChangeDetection) { + const runAfterChangeDetection = this._runAfterChangeDetection; + this._runAfterChangeDetection = []; + for (const fn of runAfterChangeDetection) { fn(); } - this._runAfterChangeDetection = []; } } diff --git a/src/demo-app/virtual-scroll/virtual-scroll-demo.ts b/src/demo-app/virtual-scroll/virtual-scroll-demo.ts index 8aff47670d97..c5570f197641 100644 --- a/src/demo-app/virtual-scroll/virtual-scroll-demo.ts +++ b/src/demo-app/virtual-scroll/virtual-scroll-demo.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Component, ViewEncapsulation} from '@angular/core'; +import {ChangeDetectionStrategy, Component, ViewEncapsulation} from '@angular/core'; import {BehaviorSubject} from 'rxjs'; @@ -22,6 +22,7 @@ type State = { templateUrl: 'virtual-scroll-demo.html', styleUrls: ['virtual-scroll-demo.css'], encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, }) export class VirtualScrollDemo { fixedSizeData = Array(10000).fill(50);