mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
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:
committed by
Joey Perrott
parent
3607677939
commit
4ff1c95ae7
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user