Skip to content

Commit c9354d8

Browse files
authored
virtual-scroll: simplify scroll listener logic (#10102)
1 parent 57576eb commit c9354d8

File tree

2 files changed

+16
-43
lines changed

2 files changed

+16
-43
lines changed

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

Lines changed: 15 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
ChangeDetectionStrategy,
1212
ChangeDetectorRef,
1313
Component,
14-
DoCheck,
1514
ElementRef,
1615
Inject,
1716
Input,
@@ -24,11 +23,19 @@ import {
2423
import {Observable} from 'rxjs/Observable';
2524
import {fromEvent} from 'rxjs/observable/fromEvent';
2625
import {takeUntil} from 'rxjs/operators/takeUntil';
26+
import {throttleTime} from 'rxjs/operators/throttleTime';
27+
import {animationFrame} from 'rxjs/scheduler/animationFrame';
2728
import {Subject} from 'rxjs/Subject';
2829
import {CdkVirtualForOf} from './virtual-for-of';
2930
import {VIRTUAL_SCROLL_STRATEGY, VirtualScrollStrategy} from './virtual-scroll-strategy';
3031

3132

33+
/** Checks if the given ranges are equal. */
34+
function rangesEqual(r1: Range, r2: Range): boolean {
35+
return r1.start == r2.start && r1.end == r2.end;
36+
}
37+
38+
3239
/** A viewport that virtualizes it's scrolling with the help of `CdkVirtualForOf`. */
3340
@Component({
3441
moduleId: module.id,
@@ -42,7 +49,7 @@ import {VIRTUAL_SCROLL_STRATEGY, VirtualScrollStrategy} from './virtual-scroll-s
4249
changeDetection: ChangeDetectionStrategy.OnPush,
4350
preserveWhitespaces: false,
4451
})
45-
export class CdkVirtualScrollViewport implements OnInit, DoCheck, OnDestroy {
52+
export class CdkVirtualScrollViewport implements OnInit, OnDestroy {
4653
/** Emits when the viewport is detached from a CdkVirtualForOf. */
4754
private _detachedSubject = new Subject<void>();
4855

@@ -78,14 +85,6 @@ export class CdkVirtualScrollViewport implements OnInit, DoCheck, OnDestroy {
7885
/** Whether this viewport is attached to a CdkVirtualForOf. */
7986
private _isAttached = false;
8087

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-
8988
constructor(public elementRef: ElementRef, private _changeDetectorRef: ChangeDetectorRef,
9089
private _ngZone: NgZone,
9190
@Inject(VIRTUAL_SCROLL_STRATEGY) private _scrollStrategy: VirtualScrollStrategy) {}
@@ -118,7 +117,7 @@ export class CdkVirtualScrollViewport implements OnInit, DoCheck, OnDestroy {
118117

119118
/** Sets the currently rendered range of indices. */
120119
setRenderedRange(range: Range) {
121-
if (!this._rangesEqual(this._renderedRange, range)) {
120+
if (!rangesEqual(this._renderedRange, range)) {
122121
// Re-enter the Angular zone so we can mark for change detection.
123122
this._ngZone.run(() => {
124123
this._renderedRangeSubject.next(this._renderedRange = range);
@@ -174,25 +173,16 @@ export class CdkVirtualScrollViewport implements OnInit, DoCheck, OnDestroy {
174173
Promise.resolve().then(() => {
175174
this._viewportSize = this.orientation === 'horizontal' ?
176175
this.elementRef.nativeElement.clientWidth : this.elementRef.nativeElement.clientHeight;
176+
this._scrollStrategy.attach(this);
177+
177178
this._ngZone.runOutsideAngular(() => {
178-
fromEvent(this.elementRef.nativeElement, 'scroll').subscribe(() => {
179-
this._markScrolled();
180-
});
179+
fromEvent(this.elementRef.nativeElement, 'scroll')
180+
.pipe(throttleTime(0, animationFrame))
181+
.subscribe(() => this._scrollStrategy.onContentScrolled());
181182
});
182-
this._scrollStrategy.attach(this);
183183
});
184184
}
185185

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-
196186
ngOnDestroy() {
197187
this.detach();
198188
this._scrollStrategy.detach();
@@ -201,20 +191,4 @@ export class CdkVirtualScrollViewport implements OnInit, DoCheck, OnDestroy {
201191
this._detachedSubject.complete();
202192
this._renderedRangeSubject.complete();
203193
}
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-
}
220194
}

src/demo-app/demo-app/demo-module.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,11 @@ import {
6363
} from '../tabs/tabs-demo';
6464
import {ToolbarDemo} from '../toolbar/toolbar-demo';
6565
import {TooltipDemo} from '../tooltip/tooltip-demo';
66+
import {TreeDemoModule} from '../tree/tree-demo-module';
6667
import {TypographyDemo} from '../typography/typography-demo';
6768
import {VirtualScrollDemo} from '../virtual-scroll/virtual-scroll-demo';
6869
import {DemoApp, Home} from './demo-app';
6970
import {DEMO_APP_ROUTES} from './routes';
70-
import {TableDemoModule} from '../table/table-demo-module';
71-
import {TreeDemoModule} from '../tree/tree-demo-module';
7271

7372
@NgModule({
7473
imports: [

0 commit comments

Comments
 (0)