Skip to content

Commit 92856e9

Browse files
committed
refactor(multiple): remove repeater strategy token
It seems like the `_VIEW_REPEATER_STRATEGY` token was introduced as a way to tree shake the different strategies depending on which components are used. While that's true, it also makes the APIs less ergonomic since users have to remember to import additional directives to use them. These changes remove the token in favor of switching the strategy internally which means that we can't tree shake the strategies anymore, but they're relatively small (< 0.5kb minified, not gzipped).
1 parent 17c6852 commit 92856e9

File tree

7 files changed

+27
-40
lines changed

7 files changed

+27
-40
lines changed

goldens/cdk/collections/index.api.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
```ts
66

77
import * as i0 from '@angular/core';
8-
import { InjectionToken } from '@angular/core';
98
import { IterableChangeRecord } from '@angular/core';
109
import { IterableChanges } from '@angular/core';
1110
import { Observable } from 'rxjs';
@@ -110,9 +109,6 @@ export class UniqueSelectionDispatcher implements OnDestroy {
110109
// @public (undocumented)
111110
export type UniqueSelectionDispatcherListener = (id: string, name: string) => void;
112111

113-
// @public
114-
export const _VIEW_REPEATER_STRATEGY: InjectionToken<_ViewRepeater<unknown, unknown, _ViewRepeaterItemContext<unknown>>>;
115-
116112
// @public
117113
export interface _ViewRepeater<T, R, C extends _ViewRepeaterItemContext<T>> {
118114
// (undocumented)

goldens/cdk/table/index.api.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ export class CdkNoDataRow {
262262
static ɵfac: i0.ɵɵFactoryDeclaration<CdkNoDataRow, never>;
263263
}
264264

265-
// @public
265+
// @public @deprecated
266266
export class CdkRecycleRows {
267267
// (undocumented)
268268
static ɵdir: i0.ɵɵDirectiveDeclaration<CdkRecycleRows, "cdk-table[recycleRows], table[cdk-table][recycleRows]", never, {}, {}, never, never, true, never>;
@@ -334,6 +334,8 @@ export class CdkTable<T> implements AfterContentInit, AfterContentChecked, Colle
334334
// (undocumented)
335335
static ngAcceptInputType_multiTemplateDataRows: unknown;
336336
// (undocumented)
337+
static ngAcceptInputType_recycleRows: unknown;
338+
// (undocumented)
337339
ngAfterContentChecked(): void;
338340
// (undocumented)
339341
ngAfterContentInit(): void;
@@ -345,6 +347,7 @@ export class CdkTable<T> implements AfterContentInit, AfterContentChecked, Colle
345347
// (undocumented)
346348
_noDataRowOutlet: NoDataRowOutlet;
347349
_outletAssigned(): void;
350+
recycleRows: boolean;
348351
removeColumnDef(columnDef: CdkColumnDef): void;
349352
removeFooterRowDef(footerRowDef: CdkFooterRowDef): void;
350353
removeHeaderRowDef(headerRowDef: CdkHeaderRowDef): void;
@@ -366,9 +369,9 @@ export class CdkTable<T> implements AfterContentInit, AfterContentChecked, Colle
366369
end: number;
367370
}>;
368371
// (undocumented)
369-
protected readonly _viewRepeater: _ViewRepeater<T, RenderRow<T>, RowContext<T>>;
372+
protected _viewRepeater: _ViewRepeater<T, RenderRow<T>, RowContext<T>>;
370373
// (undocumented)
371-
static ɵcmp: i0.ɵɵComponentDeclaration<CdkTable<any>, "cdk-table, table[cdk-table]", ["cdkTable"], { "trackBy": { "alias": "trackBy"; "required": false; }; "dataSource": { "alias": "dataSource"; "required": false; }; "multiTemplateDataRows": { "alias": "multiTemplateDataRows"; "required": false; }; "fixedLayout": { "alias": "fixedLayout"; "required": false; }; }, { "contentChanged": "contentChanged"; }, ["_noDataRow", "_contentColumnDefs", "_contentRowDefs", "_contentHeaderRowDefs", "_contentFooterRowDefs"], ["caption", "colgroup, col", "*"], true, never>;
374+
static ɵcmp: i0.ɵɵComponentDeclaration<CdkTable<any>, "cdk-table, table[cdk-table]", ["cdkTable"], { "trackBy": { "alias": "trackBy"; "required": false; }; "dataSource": { "alias": "dataSource"; "required": false; }; "multiTemplateDataRows": { "alias": "multiTemplateDataRows"; "required": false; }; "fixedLayout": { "alias": "fixedLayout"; "required": false; }; "recycleRows": { "alias": "recycleRows"; "required": false; }; }, { "contentChanged": "contentChanged"; }, ["_noDataRow", "_contentColumnDefs", "_contentRowDefs", "_contentHeaderRowDefs", "_contentFooterRowDefs"], ["caption", "colgroup, col", "*"], true, never>;
372375
// (undocumented)
373376
static ɵfac: i0.ɵɵFactoryDeclaration<CdkTable<any>, never>;
374377
}

goldens/material/table/index.api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ export class MatNoDataRow extends CdkNoDataRow {
139139
static ɵfac: i0.ɵɵFactoryDeclaration<MatNoDataRow, never>;
140140
}
141141

142-
// @public
142+
// @public @deprecated
143143
export class MatRecycleRows {
144144
// (undocumented)
145145
static ɵdir: i0.ɵɵDirectiveDeclaration<MatRecycleRows, "mat-table[recycleRows], table[mat-table][recycleRows]", never, {}, {}, never, never, true, never>;

src/cdk/collections/view-repeater.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,3 @@ export interface _ViewRepeater<T, R, C extends _ViewRepeaterItemContext<T>> {
110110

111111
detach(): void;
112112
}
113-
114-
/**
115-
* Injection token for `_ViewRepeater`. This token is for use by Angular Material only.
116-
* @docs-private
117-
*/
118-
export const _VIEW_REPEATER_STRATEGY = new InjectionToken<
119-
_ViewRepeater<unknown, unknown, _ViewRepeaterItemContext<unknown>>
120-
>('_ViewRepeater');

src/cdk/scrolling/virtual-for-of.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
ListRange,
1414
isDataSource,
1515
_RecycleViewRepeaterStrategy,
16-
_VIEW_REPEATER_STRATEGY,
1716
_ViewRepeaterItemInsertArgs,
1817
} from '../collections';
1918
import {
@@ -80,16 +79,14 @@ function getOffset(orientation: 'horizontal' | 'vertical', direction: 'start' |
8079
*/
8180
@Directive({
8281
selector: '[cdkVirtualFor][cdkVirtualForOf]',
83-
providers: [{provide: _VIEW_REPEATER_STRATEGY, useClass: _RecycleViewRepeaterStrategy}],
8482
})
8583
export class CdkVirtualForOf<T>
8684
implements CdkVirtualScrollRepeater<T>, CollectionViewer, DoCheck, OnDestroy
8785
{
8886
private _viewContainerRef = inject(ViewContainerRef);
8987
private _template = inject<TemplateRef<CdkVirtualForOfContext<T>>>(TemplateRef);
9088
private _differs = inject(IterableDiffers);
91-
private _viewRepeater =
92-
inject<_RecycleViewRepeaterStrategy<T, T, CdkVirtualForOfContext<T>>>(_VIEW_REPEATER_STRATEGY);
89+
private _viewRepeater = new _RecycleViewRepeaterStrategy<T, T, CdkVirtualForOfContext<T>>();
9390
private _viewport = inject(CdkVirtualScrollViewport, {skipSelf: true});
9491

9592
/** Emits when the rendered view of the data changes. */

src/cdk/table/table.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
_DisposeViewRepeaterStrategy,
1414
_RecycleViewRepeaterStrategy,
1515
isDataSource,
16-
_VIEW_REPEATER_STRATEGY,
1716
_ViewRepeater,
1817
_ViewRepeaterItemChange,
1918
_ViewRepeaterItemInsertArgs,
@@ -87,11 +86,11 @@ import {CDK_TABLE} from './tokens';
8786
/**
8887
* Enables the recycle view repeater strategy, which reduces rendering latency. Not compatible with
8988
* tables that animate rows.
89+
*
90+
* @deprecated This directive is a no-op and will be removed.
91+
* @breaking-change 23.0.0
9092
*/
91-
@Directive({
92-
selector: 'cdk-table[recycleRows], table[cdk-table][recycleRows]',
93-
providers: [{provide: _VIEW_REPEATER_STRATEGY, useClass: _RecycleViewRepeaterStrategy}],
94-
})
93+
@Directive({selector: 'cdk-table[recycleRows], table[cdk-table][recycleRows]'})
9594
export class CdkRecycleRows {}
9695

9796
/** Interface used to provide an outlet for rows to be inserted into. */
@@ -268,7 +267,6 @@ export interface RenderRow<T> {
268267
changeDetection: ChangeDetectionStrategy.Default,
269268
providers: [
270269
{provide: CDK_TABLE, useExisting: CdkTable},
271-
{provide: _VIEW_REPEATER_STRATEGY, useClass: _DisposeViewRepeaterStrategy},
272270
// Prevent nested tables from seeing this table's StickyPositioningListener.
273271
{provide: STICKY_POSITIONING_LISTENER, useValue: null},
274272
],
@@ -282,8 +280,7 @@ export class CdkTable<T>
282280
protected readonly _elementRef = inject(ElementRef);
283281
protected readonly _dir = inject(Directionality, {optional: true});
284282
private _platform = inject(Platform);
285-
protected readonly _viewRepeater =
286-
inject<_ViewRepeater<T, RenderRow<T>, RowContext<T>>>(_VIEW_REPEATER_STRATEGY);
283+
protected _viewRepeater: _ViewRepeater<T, RenderRow<T>, RowContext<T>>;
287284
private readonly _viewportRuler = inject(ViewportRuler);
288285
protected readonly _stickyPositioningListener = inject<StickyPositioningListener>(
289286
STICKY_POSITIONING_LISTENER,
@@ -544,6 +541,12 @@ export class CdkTable<T>
544541
}
545542
private _fixedLayout: boolean = false;
546543

544+
/**
545+
* Whether rows should be recycled which reduces latency, but is not compatible with tables
546+
* that animate rows. Note that this input cannot change after the table is initialized.
547+
*/
548+
@Input({transform: booleanAttribute}) recycleRows = false;
549+
547550
/**
548551
* Emits when the table completes rendering a set of data rows based on the latest data from the
549552
* data source, even if the set of rows is empty.
@@ -628,6 +631,9 @@ export class CdkTable<T>
628631
}
629632

630633
ngAfterContentInit() {
634+
this._viewRepeater = this.recycleRows
635+
? new _RecycleViewRepeaterStrategy()
636+
: new _DisposeViewRepeaterStrategy();
631637
this._hasInitialized = true;
632638
}
633639

src/material/table/table.ts

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,16 @@ import {
1616
NoDataRowOutlet,
1717
FooterRowOutlet,
1818
} from '@angular/cdk/table';
19-
import {
20-
_DisposeViewRepeaterStrategy,
21-
_RecycleViewRepeaterStrategy,
22-
_VIEW_REPEATER_STRATEGY,
23-
} from '@angular/cdk/collections';
19+
import {_DisposeViewRepeaterStrategy, _RecycleViewRepeaterStrategy} from '@angular/cdk/collections';
2420

2521
/**
2622
* Enables the recycle view repeater strategy, which reduces rendering latency. Not compatible with
2723
* tables that animate rows.
24+
*
25+
* @deprecated This directive is a no-op and will be removed.
26+
* @breaking-change 23.0.0
2827
*/
29-
@Directive({
30-
selector: 'mat-table[recycleRows], table[mat-table][recycleRows]',
31-
providers: [{provide: _VIEW_REPEATER_STRATEGY, useClass: _RecycleViewRepeaterStrategy}],
32-
})
28+
@Directive({selector: 'mat-table[recycleRows], table[mat-table][recycleRows]'})
3329
export class MatRecycleRows {}
3430

3531
@Component({
@@ -75,9 +71,6 @@ export class MatRecycleRows {}
7571
providers: [
7672
{provide: CdkTable, useExisting: MatTable},
7773
{provide: CDK_TABLE, useExisting: MatTable},
78-
// TODO(michaeljamesparsons) Abstract the view repeater strategy to a directive API so this code
79-
// is only included in the build if used.
80-
{provide: _VIEW_REPEATER_STRATEGY, useClass: _DisposeViewRepeaterStrategy},
8174
// Prevent nested tables from seeing this table's StickyPositioningListener.
8275
{provide: STICKY_POSITIONING_LISTENER, useValue: null},
8376
],

0 commit comments

Comments
 (0)