Skip to content

Commit 27fe795

Browse files
committed
refactor(cdk/table): add internal opt out for virtual scrolling
Adds an opt out that we can use internally to opt apps out of virtual scrolling. This allows us to keep the public API clean for the majority of users.
1 parent 5110a76 commit 27fe795

File tree

1 file changed

+27
-16
lines changed

1 file changed

+27
-16
lines changed

src/cdk/table/table.ts

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)