Skip to content

Commit 58341a7

Browse files
authored
feat(cdk/table): add API for registering no data row (#20658)
We have APIs that allow for rows and cells to be registered programmatically for cases where they aren't descendants of the table, but we didn't have something similar for the "no data" row. These changes add a method and update the examples. Fixes #20560.
1 parent de7e684 commit 58341a7

File tree

6 files changed

+54
-5
lines changed

6 files changed

+54
-5
lines changed

src/cdk/table/table.spec.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {BehaviorSubject, combineLatest, Observable, of as observableOf} from 'rx
1515
import {map} from 'rxjs/operators';
1616
import {CdkColumnDef} from './cell';
1717
import {CdkTableModule} from './index';
18-
import {CdkHeaderRowDef, CdkRowDef, CdkCellOutlet} from './row';
18+
import {CdkHeaderRowDef, CdkRowDef, CdkCellOutlet, CdkNoDataRow} from './row';
1919
import {CdkTable} from './table';
2020
import {
2121
getTableDuplicateColumnNameError,
@@ -703,6 +703,15 @@ describe('CdkTable', () => {
703703
]);
704704
});
705705

706+
it('should be able to register a no data row defined outside the table', () => {
707+
setupTableTestApp(OuterTableApp, [WrapperCdkTableApp]);
708+
709+
fixture.componentInstance.dataSource.data = [];
710+
fixture.detectChanges();
711+
712+
expect(tableElement.textContent).toContain('No data');
713+
});
714+
706715
describe('using when predicate', () => {
707716
it('should be able to display different row templates based on the row data', () => {
708717
setupTableTestApp(WhenRowCdkTableApp);
@@ -2308,13 +2317,15 @@ class RowContextCdkTableApp {
23082317
</ng-container>
23092318
23102319
<cdk-row *cdkRowDef="let row; columns: columns"></cdk-row>
2320+
<ng-template cdkNoDataRow>No data</ng-template>
23112321
</cdk-table>
23122322
`
23132323
})
23142324
class WrapperCdkTableApp<T> implements AfterContentInit {
23152325
@ContentChildren(CdkColumnDef) columnDefs: QueryList<CdkColumnDef>;
23162326
@ContentChild(CdkHeaderRowDef) headerRowDef: CdkHeaderRowDef;
23172327
@ContentChildren(CdkRowDef) rowDefs: QueryList<CdkRowDef<T>>;
2328+
@ContentChild(CdkNoDataRow) noDataRow: CdkNoDataRow;
23182329

23192330
@ViewChild(CdkTable, {static: true}) table: CdkTable<T>;
23202331

@@ -2326,6 +2337,7 @@ class WrapperCdkTableApp<T> implements AfterContentInit {
23262337
this.columnDefs.forEach(columnDef => this.table.addColumnDef(columnDef));
23272338
this.rowDefs.forEach(rowDef => this.table.addRowDef(rowDef));
23282339
this.table.addHeaderRowDef(this.headerRowDef);
2340+
this.table.setNoDataRow(this.noDataRow);
23292341
}
23302342
}
23312343

src/cdk/table/table.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,9 @@ export class CdkTable<T> implements AfterContentChecked, CollectionViewer, OnDes
281281
*/
282282
private _customFooterRowDefs = new Set<CdkFooterRowDef>();
283283

284+
/** No data row that was defined outside of the direct content children of the table. */
285+
private _customNoDataRow: CdkNoDataRow | null;
286+
284287
/**
285288
* Whether the header row definition has been changed. Triggers an update to the header row after
286289
* content is checked. Initialized as true so that the table renders the initial set of rows.
@@ -694,6 +697,11 @@ export class CdkTable<T> implements AfterContentChecked, CollectionViewer, OnDes
694697
this._footerRowDefChanged = true;
695698
}
696699

700+
/** Sets a no data row definition that was not included as a part of the content children. */
701+
setNoDataRow(noDataRow: CdkNoDataRow | null) {
702+
this._customNoDataRow = noDataRow;
703+
}
704+
697705
/**
698706
* Updates the header sticky styles. First resets all applied styles with respect to the cells
699707
* sticking to the top. Then, evaluating which cells need to be stuck to the top. This is
@@ -1228,12 +1236,14 @@ export class CdkTable<T> implements AfterContentChecked, CollectionViewer, OnDes
12281236

12291237
/** Creates or removes the no data row, depending on whether any data is being shown. */
12301238
private _updateNoDataRow() {
1231-
if (this._noDataRow) {
1239+
const noDataRow = this._customNoDataRow || this._noDataRow;
1240+
1241+
if (noDataRow) {
12321242
const shouldShow = this._rowOutlet.viewContainer.length === 0;
12331243

12341244
if (shouldShow !== this._isShowingNoDataRow) {
12351245
const container = this._noDataRowOutlet.viewContainer;
1236-
shouldShow ? container.createEmbeddedView(this._noDataRow.templateRef) : container.clear();
1246+
shouldShow ? container.createEmbeddedView(noDataRow.templateRef) : container.clear();
12371247
this._isShowingNoDataRow = shouldShow;
12381248
}
12391249
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
table {
22
width: 100%;
33
}
4+
5+
button {
6+
margin: 0 8px 8px 0;
7+
}

src/components-examples/material/table/table-wrapped/table-wrapped-example.html

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
<div>
2+
<button mat-raised-button (click)="clearTable()">Clear table</button>
3+
<button mat-raised-button (click)="addData()">Add data</button>
4+
</div>
5+
16
<wrapper-table [dataSource]="dataSource" [columns]="displayedColumns"
27
matSort #sort="matSort">
38
<!-- Custom column definition to be provided to the wrapper table. -->
@@ -8,5 +13,10 @@
813

914
<!-- Custom row definitions to be provided to the wrapper table. -->
1015
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
11-
<tr mat-row *matRowDef="let row; columns: displayedColumns; "></tr>
16+
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
17+
18+
<!-- Row shown when there is no matching data that will be provided to the wrapper table. -->
19+
<tr class="mat-row" *matNoDataRow>
20+
<td class="mat-cell" colspan="4">No data</td>
21+
</tr>
1222
</wrapper-table>

src/components-examples/material/table/table-wrapped/table-wrapped-example.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ import {
66
Input,
77
AfterViewInit,
88
QueryList,
9-
ViewChild
9+
ViewChild,
10+
ContentChild,
1011
} from '@angular/core';
1112
import {MatSort} from '@angular/material/sort';
1213
import {
1314
MatColumnDef,
1415
MatHeaderRowDef,
16+
MatNoDataRow,
1517
MatRowDef,
1618
MatTable,
1719
MatTableDataSource
@@ -54,6 +56,14 @@ export class TableWrappedExample implements AfterViewInit {
5456
ngAfterViewInit() {
5557
this.dataSource.sort = this.sort;
5658
}
59+
60+
clearTable() {
61+
this.dataSource.data = [];
62+
}
63+
64+
addData() {
65+
this.dataSource.data = ELEMENT_DATA;
66+
}
5767
}
5868

5969
/**
@@ -73,6 +83,7 @@ export class WrapperTable<T> implements AfterContentInit {
7383
@ContentChildren(MatHeaderRowDef) headerRowDefs: QueryList<MatHeaderRowDef>;
7484
@ContentChildren(MatRowDef) rowDefs: QueryList<MatRowDef<T>>;
7585
@ContentChildren(MatColumnDef) columnDefs: QueryList<MatColumnDef>;
86+
@ContentChild(MatNoDataRow) noDataRow: MatNoDataRow;
7687

7788
@ViewChild(MatTable, {static: true}) table: MatTable<T>;
7889

@@ -84,5 +95,6 @@ export class WrapperTable<T> implements AfterContentInit {
8495
this.columnDefs.forEach(columnDef => this.table.addColumnDef(columnDef));
8596
this.rowDefs.forEach(rowDef => this.table.addRowDef(rowDef));
8697
this.headerRowDefs.forEach(headerRowDef => this.table.addHeaderRowDef(headerRowDef));
98+
this.table.setNoDataRow(this.noDataRow);
8799
}
88100
}

tools/public_api_guard/cdk/table.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ export declare class CdkTable<T> implements AfterContentChecked, CollectionViewe
234234
removeHeaderRowDef(headerRowDef: CdkHeaderRowDef): void;
235235
removeRowDef(rowDef: CdkRowDef<T>): void;
236236
renderRows(): void;
237+
setNoDataRow(noDataRow: CdkNoDataRow | null): void;
237238
updateStickyColumnStyles(): void;
238239
updateStickyFooterRowStyles(): void;
239240
updateStickyHeaderRowStyles(): void;

0 commit comments

Comments
 (0)