diff --git a/src/cdk/scrolling/virtual-scroll-viewport.ts b/src/cdk/scrolling/virtual-scroll-viewport.ts index 6fa533b9784f..4222b8843058 100644 --- a/src/cdk/scrolling/virtual-scroll-viewport.ts +++ b/src/cdk/scrolling/virtual-scroll-viewport.ts @@ -278,7 +278,7 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On this._dataLength = newLength; this._scrollStrategy.onDataLengthChanged(); } - this._doChangeDetection(); + this.ngZone.runOutsideAngular(() => queueMicrotask(() => this._doChangeDetection())); }); }); } @@ -496,11 +496,7 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On // properties sequentially we only have to run `_doChangeDetection` once at the end. if (!this._isChangeDetectionPending) { this._isChangeDetectionPending = true; - this.ngZone.runOutsideAngular(() => - Promise.resolve().then(() => { - this._doChangeDetection(); - }), - ); + this.ngZone.runOutsideAngular(() => queueMicrotask(() => this._doChangeDetection())); } } @@ -511,15 +507,20 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On } this.ngZone.run(() => { + // 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._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 + // the `Number` function first to coerce it to a numeric value. + this._contentWrapper.nativeElement.style.transform = this._renderedContentTransform; + afterNextRender( () => { this._isChangeDetectionPending = false; - // 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 - // the `Number` function first to coerce it to a numeric value. - this._contentWrapper.nativeElement.style.transform = this._renderedContentTransform; const runAfterChangeDetection = this._runAfterChangeDetection; this._runAfterChangeDetection = []; for (const fn of runAfterChangeDetection) {