8
8
9
9
import { Directionality } from '@angular/cdk/bidi' ;
10
10
import { ListRange } from '@angular/cdk/collections' ;
11
+ import { Platform } from '@angular/cdk/platform' ;
11
12
import {
13
+ afterNextRender ,
12
14
booleanAttribute ,
13
15
ChangeDetectionStrategy ,
14
16
ChangeDetectorRef ,
15
17
Component ,
16
18
ElementRef ,
17
19
inject ,
18
20
Inject ,
21
+ Injector ,
19
22
Input ,
20
23
NgZone ,
21
24
OnDestroy ,
@@ -25,21 +28,20 @@ import {
25
28
ViewChild ,
26
29
ViewEncapsulation ,
27
30
} from '@angular/core' ;
28
- import { Platform } from '@angular/cdk/platform' ;
29
31
import {
30
32
animationFrameScheduler ,
31
33
asapScheduler ,
32
34
Observable ,
33
- Subject ,
34
35
Observer ,
36
+ Subject ,
35
37
Subscription ,
36
38
} from 'rxjs' ;
37
39
import { auditTime , startWith , takeUntil } from 'rxjs/operators' ;
38
40
import { ScrollDispatcher } from './scroll-dispatcher' ;
39
41
import { CdkScrollable , ExtendedScrollToOptions } from './scrollable' ;
40
- import { VIRTUAL_SCROLL_STRATEGY , VirtualScrollStrategy } from './virtual-scroll-strategy' ;
41
42
import { ViewportRuler } from './viewport-ruler' ;
42
43
import { CdkVirtualScrollRepeater } from './virtual-scroll-repeater' ;
44
+ import { VIRTUAL_SCROLL_STRATEGY , VirtualScrollStrategy } from './virtual-scroll-strategy' ;
43
45
import { CdkVirtualScrollable , VIRTUAL_SCROLLABLE } from './virtual-scrollable' ;
44
46
45
47
/** Checks if the given ranges are equal. */
@@ -173,6 +175,10 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On
173
175
/** Subscription to changes in the viewport size. */
174
176
private _viewportChanges = Subscription . EMPTY ;
175
177
178
+ private _injector = inject ( Injector ) ;
179
+
180
+ private _isDestroyed = false ;
181
+
176
182
constructor (
177
183
public override elementRef : ElementRef < HTMLElement > ,
178
184
private _changeDetectorRef : ChangeDetectorRef ,
@@ -250,6 +256,8 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On
250
256
this . _detachedSubject . complete ( ) ;
251
257
this . _viewportChanges . unsubscribe ( ) ;
252
258
259
+ this . _isDestroyed = true ;
260
+
253
261
super . ngOnDestroy ( ) ;
254
262
}
255
263
@@ -498,23 +506,29 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On
498
506
499
507
/** Run change detection. */
500
508
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 ;
517
511
}
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
+ } ) ;
518
532
}
519
533
520
534
/** Calculates the `style.width` and `style.height` for the spacer element. */
0 commit comments