88
99import { Directionality } from '@angular/cdk/bidi' ;
1010import { ListRange } from '@angular/cdk/collections' ;
11+ import { Platform } from '@angular/cdk/platform' ;
1112import {
13+ afterNextRender ,
1214 booleanAttribute ,
1315 ChangeDetectionStrategy ,
1416 ChangeDetectorRef ,
1517 Component ,
1618 ElementRef ,
1719 inject ,
1820 Inject ,
21+ Injector ,
1922 Input ,
2023 NgZone ,
2124 OnDestroy ,
@@ -25,21 +28,20 @@ import {
2528 ViewChild ,
2629 ViewEncapsulation ,
2730} from '@angular/core' ;
28- import { Platform } from '@angular/cdk/platform' ;
2931import {
3032 animationFrameScheduler ,
3133 asapScheduler ,
3234 Observable ,
33- Subject ,
3435 Observer ,
36+ Subject ,
3537 Subscription ,
3638} from 'rxjs' ;
3739import { auditTime , startWith , takeUntil } from 'rxjs/operators' ;
3840import { ScrollDispatcher } from './scroll-dispatcher' ;
3941import { CdkScrollable , ExtendedScrollToOptions } from './scrollable' ;
40- import { VIRTUAL_SCROLL_STRATEGY , VirtualScrollStrategy } from './virtual-scroll-strategy' ;
4142import { ViewportRuler } from './viewport-ruler' ;
4243import { CdkVirtualScrollRepeater } from './virtual-scroll-repeater' ;
44+ import { VIRTUAL_SCROLL_STRATEGY , VirtualScrollStrategy } from './virtual-scroll-strategy' ;
4345import { CdkVirtualScrollable , VIRTUAL_SCROLLABLE } from './virtual-scrollable' ;
4446
4547/** Checks if the given ranges are equal. */
@@ -173,6 +175,10 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On
173175 /** Subscription to changes in the viewport size. */
174176 private _viewportChanges = Subscription . EMPTY ;
175177
178+ private _injector = inject ( Injector ) ;
179+
180+ private _isDestroyed = false ;
181+
176182 constructor (
177183 public override elementRef : ElementRef < HTMLElement > ,
178184 private _changeDetectorRef : ChangeDetectorRef ,
@@ -250,6 +256,8 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On
250256 this . _detachedSubject . complete ( ) ;
251257 this . _viewportChanges . unsubscribe ( ) ;
252258
259+ this . _isDestroyed = true ;
260+
253261 super . ngOnDestroy ( ) ;
254262 }
255263
@@ -498,23 +506,29 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On
498506
499507 /** Run change detection. */
500508 private _doChangeDetection ( ) {
501- this . _isChangeDetectionPending = false ;
502-
503- // Apply the content transform. The transform can't be set via an Angular binding because
504- // bypassSecurityTrustStyle is banned in Google. However the value is safe, it's composed of
505- // string literals, a variable that can only be 'X' or 'Y', and user input that is run through
506- // the `Number` function first to coerce it to a numeric value.
507- this . _contentWrapper . nativeElement . style . transform = this . _renderedContentTransform ;
508- // Apply changes to Angular bindings. Note: We must call `markForCheck` to run change detection
509- // from the root, since the repeated items are content projected in. Calling `detectChanges`
510- // instead does not properly check the projected content.
511- this . ngZone . run ( ( ) => this . _changeDetectorRef . markForCheck ( ) ) ;
512-
513- const runAfterChangeDetection = this . _runAfterChangeDetection ;
514- this . _runAfterChangeDetection = [ ] ;
515- for ( const fn of runAfterChangeDetection ) {
516- fn ( ) ;
509+ if ( this . _isDestroyed ) {
510+ return ;
517511 }
512+
513+ this . ngZone . run ( ( ) => {
514+ this . _changeDetectorRef . markForCheck ( ) ;
515+ afterNextRender (
516+ ( ) => {
517+ this . _isChangeDetectionPending = false ;
518+ // Apply the content transform. The transform can't be set via an Angular binding because
519+ // bypassSecurityTrustStyle is banned in Google. However the value is safe, it's composed of
520+ // string literals, a variable that can only be 'X' or 'Y', and user input that is run through
521+ // the `Number` function first to coerce it to a numeric value.
522+ this . _contentWrapper . nativeElement . style . transform = this . _renderedContentTransform ;
523+ const runAfterChangeDetection = this . _runAfterChangeDetection ;
524+ this . _runAfterChangeDetection = [ ] ;
525+ for ( const fn of runAfterChangeDetection ) {
526+ fn ( ) ;
527+ }
528+ } ,
529+ { injector : this . _injector } ,
530+ ) ;
531+ } ) ;
518532 }
519533
520534 /** Calculates the `style.width` and `style.height` for the spacer element. */
0 commit comments