|
| 1 | +The CDK Data Table displays rows of data with fully customizable cell templates. |
| 2 | +Its single responsibility is the efficient rendering of rows in a fully accessible way. |
| 3 | + |
| 4 | +The CDK table provides a foundation upon which other features, such as sorting and pagination, can be built. |
| 5 | +Because the CDK table enforces no opinions on these matters, developers have full control over the interaction patterns associated with the table. |
| 6 | + |
| 7 | +For a Material Design styled table, see `<md-table>`, which builds on top of the CDK Data Table. |
| 8 | + |
| 9 | +In the near future, the material library will include an additional "simple table", |
| 10 | +building `<md-table>` with a more minimal interface and sorting, pagination, and selection built-in. |
| 11 | + |
| 12 | +<!-- example(table-basic) --> |
| 13 | + |
| 14 | +## Using the CDK Data Table |
| 15 | + |
| 16 | +### Writing your table template |
| 17 | + |
| 18 | +The first step to writing the CDK Data Table template is to define the columns that will be used in your table. |
| 19 | +Each column definition will consist of a header cell template and a data cell template by using |
| 20 | +the `<cdk-header-cell>` and `<cdk-cell>`, respectively. These will be wrapped in an `<ng-container>` and given a column name. |
| 21 | + |
| 22 | +Both the `<cdk-header-cell>` and `<cdk-cell>` require an additional directive so that the table can |
| 23 | +capture the inner template. For `<cdk-header-cell>` you must include the attribute `*cdkHeaderCellDef` |
| 24 | +and for `<cdk-cell>` you must include `*cdkCellDef`. Note that the `*cdkCellDef` provides an outlet |
| 25 | +to capture the cell’s row data to be used in the template. |
| 26 | + |
| 27 | +```html |
| 28 | + <ng-container cdkColumnDef="column_a"> |
| 29 | + <cdk-header-cell *cdkHeaderCellDef> Column A </cdk-header-cell> |
| 30 | + <cdk-cell *cdkCellDef="let row"> {{row.a}} </cdk-cell> |
| 31 | + </ng-container> |
| 32 | +``` |
| 33 | + |
| 34 | +After the columns have been defined, you must include a `<cdk-header-row>` and `<cdk-row>` which will |
| 35 | +each take an array of the column names. This will be the columns that will be rendered in the table and in the order provided. |
| 36 | + |
| 37 | +```html |
| 38 | + <cdk-header-row *cdkHeaderRowDef="['column_a', 'column_b', 'column_c']"></cdk-header-row> |
| 39 | + <cdk-row *cdkRowDef="let row; columns: ['column_a', 'column_b', 'column_c']"></cdk-row> |
| 40 | +``` |
| 41 | + |
| 42 | +In the following template, we have a data table that displays three columns: Column A, Column B, and Column C. |
| 43 | +The <cdk-header-row> and <cdk-row> are given an input of what columns to display. |
| 44 | + |
| 45 | +```html |
| 46 | +<cdk-table [dataSource]="dataSource"> |
| 47 | + <!-- Column A Definition --> |
| 48 | + <ng-container cdkColumnDef="column_a"> |
| 49 | + <cdk-header-cell *cdkHeaderCellDef> Column A </cdk-header-cell> |
| 50 | + <cdk-cell *cdkCellDef="let row"> {{row.a}} </cdk-cell> |
| 51 | + </ng-container> |
| 52 | + |
| 53 | + <!-- Column B Definition --> |
| 54 | + <ng-container cdkColumnDef="column_b"> |
| 55 | + <cdk-header-cell *cdkHeaderCellDef> Column B </cdk-header-cell> |
| 56 | + <cdk-cell *cdkCellDef="let row"> {{row.b}} </cdk-cell> |
| 57 | + </ng-container> |
| 58 | + |
| 59 | + <!-- Column C Definition --> |
| 60 | + <ng-container cdkColumnDef="column_c"> |
| 61 | + <cdk-header-cell *cdkHeaderCellDef> Column C </cdk-header-cell> |
| 62 | + <cdk-cell *cdkCellDef="let row"> {{row.c}} </cdk-cell> |
| 63 | + </ng-container> |
| 64 | + |
| 65 | + <!-- Header and Row Declarations (define columns; provide attribute and event binding) --> |
| 66 | + <cdk-header-row *cdkHeaderRowDef="['column_a', 'column_b', 'column_c']"></cdk-header-row> |
| 67 | + <cdk-row *cdkRowDef="let row; columns: ['column_a', 'column_b', 'column_c']"></cdk-row> |
| 68 | + </cdk-table> |
| 69 | +``` |
| 70 | + |
| 71 | +It is not required to display all the columns that are defined within the template, |
| 72 | +nor is the order required. For example, if we wanted the table to display only Column B |
| 73 | +and Column A and in that order, then the template would look like this: |
| 74 | + |
| 75 | +```html |
| 76 | + <cdk-header-row *cdkHeaderRowDef="['column_b', 'column_a’]"></cdk-header-row> |
| 77 | + <cdk-row *cdkRowDef="let row; columns: ['column_b', 'column_a']"></cdk-row> |
| 78 | +``` |
| 79 | + |
| 80 | +Adding attribute and event binding to the header and rows is as simple as applying them to the |
| 81 | +<cdk-header-row> and <cdk-row>. For example, here the table is adding a click handler to both. |
| 82 | +In addition, the CSS class `a-bigger-than-twenty` will be applied to any row where its data’s `a` property is greater than 20. |
| 83 | + |
| 84 | +```html |
| 85 | + <cdk-header-row *cdkHeaderRowDef="['column_b', 'column_a']" |
| 86 | + (click)=”handleHeaderRowClick(row)”> |
| 87 | + </cdk-header-row> |
| 88 | + |
| 89 | + <cdk-row *cdkRowDef="let row; columns: ['column_b', 'column_a']" |
| 90 | + [class.a-bigger-than-twenty]=”row.a > 20” |
| 91 | + (click)=”handleRowClick(row)”> |
| 92 | + </cdk-row> |
| 93 | +``` |
| 94 | + |
| 95 | +Changing the list of columns provided to the `<cdk-header-row>` and `<cdk-row>` will automatically |
| 96 | +cause the table to re-render to reflect those changes. For more information, see Dynamic Columns below under Features. |
| 97 | + |
| 98 | +### Connecting the table to a data source |
| 99 | +Data is provided to the table through the `DataSource` interface. When the table receives a DataSource, |
| 100 | +it calls its connect function to receive an observable that emits an array of data. Whenever the Data Source emits data to this stream, the table will use it to render its rows. |
| 101 | + |
| 102 | +Since the Data Source provides this data stream, it is responsible for watching for data changes |
| 103 | +and notifying the table when to re-render. Examples of these data changes includes sorting, pagination, filtering, and more. |
| 104 | +To see how these examples can be incorporated in the Data Source, see below under Features. |
| 105 | + |
| 106 | +Note that a trackBy function can be provided to the table similar to Angular’s ngFor trackBy. |
| 107 | +This allows you to customize how the table to identifies rows and improves performance. |
| 108 | + |
| 109 | +In the future, the connect function will be able to use the CollectionViewer parameter to be |
| 110 | +notified about table events, such as what rows the user is currently viewing. This could be used to |
| 111 | +help the Data Source know what data does not need to be retrieved and rendered, further improving performance. |
| 112 | + |
| 113 | +## Material Table |
| 114 | +To use the CDK Data Table with styles matching the Material Design spec, you can use the `<md-table>` |
| 115 | +defined in `@angular/material`. This will build on the CDK Data Table and apply built-in Material Design styles. |
| 116 | + |
| 117 | +The interface for the `<md-table>` matches the `<cdk-table>`, except that its element selectors |
| 118 | +will be prefixed with `md-` instead of `cdk-`. |
| 119 | + |
| 120 | +Note that the column definition directives (`cdkColumnDef` and `cdkHeaderCellDef`) are still prefixed with `cdk-`. |
| 121 | + |
| 122 | +```html |
| 123 | +<md-table [dataSource]="dataSource"> |
| 124 | + <!-- Column A Definition --> |
| 125 | + <ng-container cdkColumnDef="column_a"> |
| 126 | + <md-header-cell *cdkHeaderCellDef> Column A </md-header-cell> |
| 127 | + <md-cell *cdkCellDef="let row"> {{row.a}} </md-cell> |
| 128 | + </ng-container> |
| 129 | + |
| 130 | + <!-- Column B Definition --> |
| 131 | + <ng-container cdkColumnDef="column_b"> |
| 132 | + <md-header-cell *cdkHeaderCellDef> Column B </md-header-cell> |
| 133 | + <md-cell *cdkCellDef="let row"> {{row.b}} </md-cell> |
| 134 | + </ng-container> |
| 135 | + |
| 136 | + <!-- Column C Definition --> |
| 137 | + <ng-container cdkColumnDef="column_c"> |
| 138 | + <md-header-cell *cdkHeaderCellDef> Column C </md-header-cell> |
| 139 | + <md-cell *cdkCellDef="let row"> {{row.c}} </md-cell> |
| 140 | + </ng-container> |
| 141 | + |
| 142 | + <!-- Header and Row Declarations (define columns; provide attribute and event binding) --> |
| 143 | + <md-header-row *cdkHeaderRowDef="['column_a', 'column_b', 'column_c']"></md-header-row> |
| 144 | + <md-row *cdkRowDef="let row; columns: ['column_a', 'column_b', 'column_c']"></md-row> |
| 145 | + </md-table> |
| 146 | +``` |
| 147 | + |
| 148 | +## Simple Table |
| 149 | + |
| 150 | +In the near future, we would like to provide a simple version of the data table that includes an easy-to-use interface, |
| 151 | +material styling, data array input, and out-of-the-box features such as sorting, pagination, and selection. |
| 152 | + |
| 153 | +## Features |
| 154 | + |
| 155 | +The CDK Table’s responsibility is to handle efficient rendering of rows and it’s the Data Source’s job |
| 156 | +to let the table know what data should be rendered. As such, features that manipulate what data should |
| 157 | +be rendered should be the responsibility of the data source. |
| 158 | + |
| 159 | +### Pagination |
| 160 | +Use the MdPagination component to add data paging to the data table. The data source can listen to |
| 161 | +paging events from the component and appropriately slice the right data from whatever data provider |
| 162 | +is used. Sending this new data to the table will cause it to render the new page of data. |
| 163 | + |
| 164 | +<!-- example(table-pagination) --> |
| 165 | + |
| 166 | +### Sorting |
| 167 | +Use the MdSort component to enable sorting the table's data through the column headers. |
| 168 | +The data source can listen to sorting events from the component and sort the data before giving it |
| 169 | +to the table to render. |
| 170 | + |
| 171 | +<!-- example(table-sorting) --> |
| 172 | + |
| 173 | +### Filtering |
| 174 | + |
| 175 | +<!--- example(table-filtering) --> |
0 commit comments