Skip to content

Commit aae045c

Browse files
committed
virtual-scroll: switch back to markForCheck since detectChanges (#12329)
breaks viewports that are inside an `OnPush` component. Fixes issue introduced by #12158
1 parent 86f85c6 commit aae045c

File tree

3 files changed

+13
-12
lines changed

3 files changed

+13
-12
lines changed

src/cdk-experimental/scrolling/virtual-scroll-viewport.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,10 @@ describe('CdkVirtualScrollViewport', () => {
101101

102102
it('should set total content size', fakeAsync(() => {
103103
finishInit(fixture);
104+
104105
viewport.setTotalContentSize(10000);
105-
fixture.detectChanges();
106106
flush();
107+
fixture.detectChanges();
107108

108109
expect(viewport.elementRef.nativeElement.scrollHeight).toBe(10000);
109110
}));

src/cdk-experimental/scrolling/virtual-scroll-viewport.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
ViewEncapsulation,
2222
} from '@angular/core';
2323
import {animationFrameScheduler, fromEvent, Observable, Subject} from 'rxjs';
24-
import {sampleTime, take, takeUntil} from 'rxjs/operators';
24+
import {sampleTime, takeUntil} from 'rxjs/operators';
2525
import {CdkVirtualForOf} from './virtual-for-of';
2626
import {VIRTUAL_SCROLL_STRATEGY, VirtualScrollStrategy} from './virtual-scroll-strategy';
2727

@@ -301,11 +301,7 @@ export class CdkVirtualScrollViewport implements OnInit, OnDestroy {
301301
if (!this._isChangeDetectionPending) {
302302
this._isChangeDetectionPending = true;
303303
this._ngZone.runOutsideAngular(() => Promise.resolve().then(() => {
304-
if (this._ngZone.isStable) {
305-
this._doChangeDetection();
306-
} else {
307-
this._ngZone.onStable.pipe(take(1)).subscribe(() => this._doChangeDetection());
308-
}
304+
this._doChangeDetection();
309305
}));
310306
}
311307
}
@@ -314,8 +310,10 @@ export class CdkVirtualScrollViewport implements OnInit, OnDestroy {
314310
private _doChangeDetection() {
315311
this._isChangeDetectionPending = false;
316312

317-
// Apply changes to Angular bindings.
318-
this._ngZone.run(() => this._changeDetectorRef.detectChanges());
313+
// Apply changes to Angular bindings. Note: We must call `markForCheck` to run change detection
314+
// from the root, since the repeated items are content projected in. Calling `detectChanges`
315+
// instead does not properly check the projected content.
316+
this._ngZone.run(() => this._changeDetectorRef.markForCheck());
319317
// Apply the content transform. The transform can't be set via an Angular binding because
320318
// bypassSecurityTrustStyle is banned in Google. However the value is safe, it's composed of
321319
// 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 {
330328
}
331329
}
332330

333-
for (const fn of this._runAfterChangeDetection) {
331+
const runAfterChangeDetection = this._runAfterChangeDetection;
332+
this._runAfterChangeDetection = [];
333+
for (const fn of runAfterChangeDetection) {
334334
fn();
335335
}
336-
this._runAfterChangeDetection = [];
337336
}
338337
}

src/demo-app/virtual-scroll/virtual-scroll-demo.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Component, ViewEncapsulation} from '@angular/core';
9+
import {ChangeDetectionStrategy, Component, ViewEncapsulation} from '@angular/core';
1010
import {BehaviorSubject} from 'rxjs';
1111

1212

@@ -22,6 +22,7 @@ type State = {
2222
templateUrl: 'virtual-scroll-demo.html',
2323
styleUrls: ['virtual-scroll-demo.css'],
2424
encapsulation: ViewEncapsulation.None,
25+
changeDetection: ChangeDetectionStrategy.OnPush,
2526
})
2627
export class VirtualScrollDemo {
2728
fixedSizeData = Array(10000).fill(50);

0 commit comments

Comments
 (0)