fix(scrolling): virtual scroll viewport error during server-side rendering (#15299)

Fixes the virtual scroll viewport throwing an error during server-side rendering, because it relies on a scheduler that uses `requestAnimationFrame`.

Fixes #15291.
This commit is contained in:
Kristiyan Kostadinov
2019-03-05 16:04:05 +01:00
committed by Joey Perrott
parent 3607677939
commit 4ff1c95ae7
3 changed files with 23 additions and 3 deletions
+10 -2
View File
@@ -23,7 +23,7 @@ import {
ViewChild,
ViewEncapsulation,
} from '@angular/core';
import {animationFrameScheduler, Observable, Subject, Observer} from 'rxjs';
import {animationFrameScheduler, asapScheduler, Observable, Subject, Observer} from 'rxjs';
import {auditTime, startWith, takeUntil} from 'rxjs/operators';
import {ScrollDispatcher} from './scroll-dispatcher';
import {CdkScrollable, ExtendedScrollToOptions} from './scrollable';
@@ -36,6 +36,14 @@ function rangesEqual(r1: ListRange, r2: ListRange): boolean {
return r1.start == r2.start && r1.end == r2.end;
}
/**
* Scheduler to be used for scroll events. Needs to fall back to
* something that doesn't rely on requestAnimationFrame on environments
* that don't support it (e.g. server-side rendering).
*/
const SCROLL_SCHEDULER =
typeof requestAnimationFrame !== 'undefined' ? animationFrameScheduler : asapScheduler;
/** A viewport that virtualizes it's scrolling with the help of `CdkVirtualForOf`. */
@Component({
@@ -157,7 +165,7 @@ export class CdkVirtualScrollViewport extends CdkScrollable implements OnInit, O
// Collect multiple events into one until the next animation frame. This way if
// there are multiple scroll events in the same frame we only need to recheck
// our layout once.
auditTime(0, animationFrameScheduler))
auditTime(0, SCROLL_SCHEDULER))
.subscribe(() => this._scrollStrategy.onContentScrolled());
this._markChangeDetectionNeeded();
@@ -372,3 +372,11 @@
<li cdkDrag>One</li>
<li cdkDrag>Two</li>
</ul>
<h2>Virtual scroll</h2>
<cdk-virtual-scroll-viewport itemSize="50">
<div *cdkVirtualFor="let size of virtualScrollData; let i = index" style="height: 50px">
Item #{{i}}
</div>
</cdk-virtual-scroll-viewport>
@@ -1,4 +1,4 @@
import {ViewportRuler} from '@angular/cdk/scrolling';
import {ViewportRuler, ScrollingModule} from '@angular/cdk/scrolling';
import {
CdkTableModule,
DataSource
@@ -77,6 +77,9 @@ export class KitchenSink {
/** Data source for the CDK and Material table. */
tableDataSource = new TableDataSource();
/** Data used to render a virtual scrolling list. */
virtualScrollData = Array(10000).fill(50);
constructor(
snackBar: MatSnackBar,
dialog: MatDialog,
@@ -135,6 +138,7 @@ export class KitchenSink {
MatSortModule,
MatTableModule,
MatStepperModule,
ScrollingModule,
// CDK Modules
CdkTableModule,