@@ -11,24 +11,30 @@ import {
11
11
ChangeDetectionStrategy ,
12
12
ChangeDetectorRef ,
13
13
Component ,
14
- DoCheck ,
15
14
ElementRef ,
16
15
Inject ,
17
16
Input ,
18
- NgZone ,
19
17
OnDestroy ,
20
18
OnInit ,
21
19
ViewChild ,
22
20
ViewEncapsulation ,
23
21
} from '@angular/core' ;
24
22
import { Observable } from 'rxjs/Observable' ;
25
23
import { fromEvent } from 'rxjs/observable/fromEvent' ;
24
+ import { throttleTime } from 'rxjs/operators' ;
26
25
import { takeUntil } from 'rxjs/operators/takeUntil' ;
26
+ import { animationFrame } from 'rxjs/scheduler/animationFrame' ;
27
27
import { Subject } from 'rxjs/Subject' ;
28
28
import { CdkVirtualForOf } from './virtual-for-of' ;
29
29
import { VIRTUAL_SCROLL_STRATEGY , VirtualScrollStrategy } from './virtual-scroll-strategy' ;
30
30
31
31
32
+ /** Checks if the given ranges are equal. */
33
+ function rangesEqual ( r1 : Range , r2 : Range ) : boolean {
34
+ return r1 . start == r2 . start && r1 . end == r2 . end ;
35
+ }
36
+
37
+
32
38
/** A viewport that virtualizes it's scrolling with the help of `CdkVirtualForOf`. */
33
39
@Component ( {
34
40
moduleId : module . id ,
@@ -42,7 +48,7 @@ import {VIRTUAL_SCROLL_STRATEGY, VirtualScrollStrategy} from './virtual-scroll-s
42
48
changeDetection : ChangeDetectionStrategy . OnPush ,
43
49
preserveWhitespaces : false ,
44
50
} )
45
- export class CdkVirtualScrollViewport implements OnInit , DoCheck , OnDestroy {
51
+ export class CdkVirtualScrollViewport implements OnInit , OnDestroy {
46
52
/** Emits when the viewport is detached from a CdkVirtualForOf. */
47
53
private _detachedSubject = new Subject < void > ( ) ;
48
54
@@ -78,16 +84,7 @@ export class CdkVirtualScrollViewport implements OnInit, DoCheck, OnDestroy {
78
84
/** Whether this viewport is attached to a CdkVirtualForOf. */
79
85
private _isAttached = false ;
80
86
81
- /**
82
- * The scroll handling status.
83
- * needed - The scroll state needs to be updated, but a check hasn't yet been scheduled.
84
- * pending - The scroll state needs to be updated, and an update has already been scheduled.
85
- * done - The scroll state does not need to be updated.
86
- */
87
- private _scrollHandledStatus : 'needed' | 'pending' | 'done' = 'done' ;
88
-
89
87
constructor ( public elementRef : ElementRef , private _changeDetectorRef : ChangeDetectorRef ,
90
- private _ngZone : NgZone ,
91
88
@Inject ( VIRTUAL_SCROLL_STRATEGY ) private _scrollStrategy : VirtualScrollStrategy ) { }
92
89
93
90
/** Gets the length of the data bound to this viewport (in number of items). */
@@ -108,22 +105,16 @@ export class CdkVirtualScrollViewport implements OnInit, DoCheck, OnDestroy {
108
105
*/
109
106
setTotalContentSize ( size : number ) {
110
107
if ( this . _totalContentSize != size ) {
111
- // Re-enter the Angular zone so we can mark for change detection.
112
- this . _ngZone . run ( ( ) => {
113
- this . _totalContentSize = size ;
114
- this . _changeDetectorRef . markForCheck ( ) ;
115
- } ) ;
108
+ this . _totalContentSize = size ;
109
+ this . _changeDetectorRef . markForCheck ( ) ;
116
110
}
117
111
}
118
112
119
113
/** Sets the currently rendered range of indices. */
120
114
setRenderedRange ( range : Range ) {
121
- if ( ! this . _rangesEqual ( this . _renderedRange , range ) ) {
122
- // Re-enter the Angular zone so we can mark for change detection.
123
- this . _ngZone . run ( ( ) => {
124
- this . _renderedRangeSubject . next ( this . _renderedRange = range ) ;
125
- this . _changeDetectorRef . markForCheck ( ) ;
126
- } ) ;
115
+ if ( ! rangesEqual ( this . _renderedRange , range ) ) {
116
+ this . _renderedRangeSubject . next ( this . _renderedRange = range ) ;
117
+ this . _changeDetectorRef . markForCheck ( ) ;
127
118
}
128
119
}
129
120
@@ -132,11 +123,8 @@ export class CdkVirtualScrollViewport implements OnInit, DoCheck, OnDestroy {
132
123
const transform =
133
124
this . orientation === 'horizontal' ? `translateX(${ offset } px)` : `translateY(${ offset } px)` ;
134
125
if ( this . _renderedContentTransform != transform ) {
135
- // Re-enter the Angular zone so we can mark for change detection.
136
- this . _ngZone . run ( ( ) => {
137
- this . _renderedContentTransform = transform ;
138
- this . _changeDetectorRef . markForCheck ( ) ;
139
- } ) ;
126
+ this . _renderedContentTransform = transform ;
127
+ this . _changeDetectorRef . markForCheck ( ) ;
140
128
}
141
129
}
142
130
@@ -174,25 +162,12 @@ export class CdkVirtualScrollViewport implements OnInit, DoCheck, OnDestroy {
174
162
Promise . resolve ( ) . then ( ( ) => {
175
163
this . _viewportSize = this . orientation === 'horizontal' ?
176
164
this . elementRef . nativeElement . clientWidth : this . elementRef . nativeElement . clientHeight ;
177
- this . _ngZone . runOutsideAngular ( ( ) => {
178
- fromEvent ( this . elementRef . nativeElement , 'scroll' ) . subscribe ( ( ) => {
179
- this . _markScrolled ( ) ;
180
- } ) ;
181
- } ) ;
165
+ fromEvent ( this . elementRef . nativeElement , 'scroll' ) . pipe ( throttleTime ( 0 , animationFrame ) )
166
+ . subscribe ( ( ) => this . _scrollStrategy . onContentScrolled ( ) ) ;
182
167
this . _scrollStrategy . attach ( this ) ;
183
168
} ) ;
184
169
}
185
170
186
- ngDoCheck ( ) {
187
- if ( this . _scrollHandledStatus === 'needed' ) {
188
- this . _scrollHandledStatus = 'pending' ;
189
- this . _ngZone . runOutsideAngular ( ( ) => requestAnimationFrame ( ( ) => {
190
- this . _scrollHandledStatus = 'done' ;
191
- this . _scrollStrategy . onContentScrolled ( ) ;
192
- } ) ) ;
193
- }
194
- }
195
-
196
171
ngOnDestroy ( ) {
197
172
this . detach ( ) ;
198
173
this . _scrollStrategy . detach ( ) ;
@@ -201,20 +176,4 @@ export class CdkVirtualScrollViewport implements OnInit, DoCheck, OnDestroy {
201
176
this . _detachedSubject . complete ( ) ;
202
177
this . _renderedRangeSubject . complete ( ) ;
203
178
}
204
-
205
- /** Marks that a scroll event happened and that the scroll state should be checked. */
206
- private _markScrolled ( ) {
207
- if ( this . _scrollHandledStatus === 'done' ) {
208
- // Re-enter the Angular zone so we can mark for change detection.
209
- this . _ngZone . run ( ( ) => {
210
- this . _scrollHandledStatus = 'needed' ;
211
- this . _changeDetectorRef . markForCheck ( ) ;
212
- } ) ;
213
- }
214
- }
215
-
216
- /** Checks if the given ranges are equal. */
217
- private _rangesEqual ( r1 : Range , r2 : Range ) : boolean {
218
- return r1 . start == r2 . start && r1 . end == r2 . end ;
219
- }
220
179
}
0 commit comments