@@ -467,6 +467,14 @@ export class CdkTable<T>
467467 /** Emits when the footer rows sticky state changes. */
468468 private readonly _footerRowStickyUpdates = new Subject < StickyUpdate > ( ) ;
469469
470+ /**
471+ * Whether to explicitly disable virtual scrolling even if there is a virtual scroll viewport
472+ * parent. This can't be changed externally, whereas internally it is turned into an input that
473+ * we use to opt out existing apps that were implementing virtual scroll before we added support
474+ * for it.
475+ */
476+ private readonly _disableVirtualScrolling = false ;
477+
470478 /** Aria role to apply to the table's cells based on the table's own role. */
471479 _getCellRole ( ) : string | null {
472480 // Perform this lazily in case the table's role was updated by a directive after construction.
@@ -565,7 +573,7 @@ export class CdkTable<T>
565573 get fixedLayout ( ) : boolean {
566574 // Require a fixed layout when virtual scrolling is enabled, otherwise
567575 // the element the header can jump around as the user is scrolling.
568- return this . _virtualScrollViewport ? true : this . _fixedLayout ;
576+ return this . _virtualScrollEnabled ( ) ? true : this . _fixedLayout ;
569577 }
570578 set fixedLayout ( value : boolean ) {
571579 this . _fixedLayout = value ;
@@ -640,7 +648,7 @@ export class CdkTable<T>
640648 this . _isNativeHtmlTable = this . _elementRef . nativeElement . nodeName === 'TABLE' ;
641649 this . viewChange = new BehaviorSubject < ListRange > ( {
642650 start : 0 ,
643- end : this . _virtualScrollViewport ? 0 : Number . MAX_VALUE ,
651+ end : this . _virtualScrollEnabled ( ) ? 0 : Number . MAX_VALUE ,
644652 } ) ;
645653
646654 // Set up the trackBy function so that it uses the `RenderRow` as its identity by default. If
@@ -649,10 +657,6 @@ export class CdkTable<T>
649657 this . _dataDiffer = this . _differs . find ( [ ] ) . create ( ( _i : number , dataRow : RenderRow < T > ) => {
650658 return this . trackBy ? this . trackBy ( dataRow . dataIndex , dataRow . data ) : dataRow ;
651659 } ) ;
652-
653- if ( this . _virtualScrollViewport ) {
654- this . _setupVirtualScrolling ( this . _virtualScrollViewport ) ;
655- }
656660 }
657661
658662 ngOnInit ( ) {
@@ -668,9 +672,14 @@ export class CdkTable<T>
668672
669673 ngAfterContentInit ( ) {
670674 this . _viewRepeater =
671- this . recycleRows || this . _virtualScrollViewport
675+ this . recycleRows || this . _virtualScrollEnabled ( )
672676 ? new _RecycleViewRepeaterStrategy ( )
673677 : new _DisposeViewRepeaterStrategy ( ) ;
678+
679+ if ( this . _virtualScrollEnabled ( ) ) {
680+ this . _setupVirtualScrolling ( this . _virtualScrollViewport ! ) ;
681+ }
682+
674683 this . _hasInitialized = true ;
675684 }
676685
@@ -1039,24 +1048,22 @@ export class CdkTable<T>
10391048 * so that the differ equates their references.
10401049 */
10411050 private _getAllRenderRows ( ) : RenderRow < T > [ ] {
1042- const dataWithinRange = this . _renderedRange
1043- ? ( this . _data || [ ] ) . slice ( this . _renderedRange . start , this . _renderedRange . end )
1044- : [ ] ;
1051+ if ( ! Array . isArray ( this . _data ) || ! this . _renderedRange ) {
1052+ return [ ] ;
1053+ }
1054+
10451055 const renderRows : RenderRow < T > [ ] = [ ] ;
1056+ const end = Math . min ( this . _data . length , this . _renderedRange . end ) ;
10461057
10471058 // Store the cache and create a new one. Any re-used RenderRow objects will be moved into the
10481059 // new cache while unused ones can be picked up by garbage collection.
10491060 const prevCachedRenderRows = this . _cachedRenderRowsMap ;
10501061 this . _cachedRenderRowsMap = new Map ( ) ;
10511062
1052- if ( ! this . _data ) {
1053- return renderRows ;
1054- }
1055-
10561063 // For each data object, get the list of rows that should be rendered, represented by the
10571064 // respective `RenderRow` object which is the pair of `data` and `CdkRowDef`.
1058- for ( let i = 0 ; i < dataWithinRange . length ; i ++ ) {
1059- let data = dataWithinRange [ i ] ;
1065+ for ( let i = this . _renderedRange . start ; i < end ; i ++ ) {
1066+ const data = this . _data [ i ] ;
10601067 const renderRowsForData = this . _getRenderRowsForData ( data , i , prevCachedRenderRows . get ( data ) ) ;
10611068
10621069 if ( ! this . _cachedRenderRowsMap . has ( data ) ) {
@@ -1629,6 +1636,10 @@ export class CdkTable<T>
16291636 const endRect = lastNode ?. getBoundingClientRect ?.( ) ;
16301637 return startRect && endRect ? endRect . bottom - startRect . top : 0 ;
16311638 }
1639+
1640+ private _virtualScrollEnabled ( ) : boolean {
1641+ return ! this . _disableVirtualScrolling && this . _virtualScrollViewport != null ;
1642+ }
16321643}
16331644
16341645/** Utility function that gets a merged list of the entries in an array and values of a Set. */
0 commit comments