The code from your example is the definition for a generic table, using the new cdk component in the material2 specification.
you must keep in mind the md-table
is the visual implementation of the cdk-table
, so you need to declare a cdk with a model compatible with the md-model in HTML.
For example:
I declare a cdk-table
with following implementation:
- First, the dependencies:
The new CDK component in Material2, using:
import { DataSource } from '@angular/cdk';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
- Definition of the structure of the HTML in TS:
I define a displayedColumns
array, the items are the columns in my HTML table, in order:
displayedColumns = ['userId', 'userName', 'progress'];
A database of the type ExampleDatabase
(an object with a manual definition particular):
exampleDatabase = new ExampleDatabase();
Finally, i declare a dataSource
, this is the origin of my data. It is an object with a manual definition or data null.
dataSource: ExampleDataSource | null;
In the ngOnInit()
method, I simply declare that my dataSource
is a new ExampleDataSource
with parameter my exampleDataBase
.
Good, now to implement the rest of the code:
First, declare an interface for the DataBase
. This is very important for maintaining the congruence of the data, the database must respect a defined scheme.
In this example, the database has three columns: id, name and progress:
export interface UserData {
id: number;
name: string;
progress: string;
}
The next point is create a class (Object) ExampleDatabase
with the definition of the data in my DataBase
. You could create a service for connecting to an actual database (PostgreSQL, MongoDB), get the real data and create the objects for the cdk-datatable in another method, however in this example we are using an in memory database emulated at run time.
export class ExampleDatabase {
/** Stream that emits whenever the data has been modified. */
dataChange: BehaviorSubject<UserData[]> = new BehaviorSubject<UserData[]>([]);
get data(): UserData[] { return this.dataChange.value; }
constructor() {
// Fill up the database with 100 users.
for (let i = 0; i < 100; i++) { this.addUser(); }
}
/** Adds a new user to the database. */
addUser() {
const copiedData = this.data.slice();
copiedData.push(this.createNewUser());
this.dataChange.next(copiedData);
}
/** Builds and returns a new User. */
private createNewUser() {
return {
id: 1,
name: 'example',
progress: Math.round(Math.random() * 100).toString()
};
}
}
Good, finally i create a second class with the definition of my DataSource
.
export class ExampleDataSource extends DataSource<any> {
constructor(private _exampleDatabase: ExampleDatabase) {
super();
}
/** Connect function called by the table to retrieve one stream containing the data to render. */
connect(): Observable<UserData[]> {
return this._exampleDatabase.dataChange;
}
disconnect() { }
}
This method makes sure the data is in the correct format, and releases the "connection" to the DataBase
(in memory) to get the data in it.
Finally, use the md-table
component or cdk-table
component in the HTML. The md-table
component uses the material design style, and the cdk-table
uses a generic style..
md-table:
<div class="example-container mat-elevation-z8">
<md-table #table [dataSource]="dataSource">
<!-- ID Column -->
<ng-container cdkColumnDef="userId">
<md-header-cell *cdkHeaderCellDef> ID </md-header-cell>
<md-cell *cdkCellDef="let row"> {{row.id}} </md-cell>
</ng-container>
<!-- Progress Column -->
<ng-container cdkColumnDef="progress">
<md-header-cell *cdkHeaderCellDef> Progress </md-header-cell>
<md-cell *cdkCellDef="let row"> {{row.progress}}% </md-cell>
</ng-container>
<!-- Name Column -->
<ng-container cdkColumnDef="userName">
<md-header-cell *cdkHeaderCellDef> Name </md-header-cell>
<md-cell *cdkCellDef="let row"> {{row.name}} </md-cell>
</ng-container>
<md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row>
<md-row *cdkRowDef="let row; columns: displayedColumns;"></md-row>
</md-table>
</div>
cdk-table:
<div class="example-container mat-elevation-z8">
<cdk-table #table [dataSource]="dataSource" class="example-table">
<!-- ID Column -->
<ng-container cdkColumnDef="userId">
<cdk-header-cell *cdkHeaderCellDef class="example-header-cell"> ID </cdk-header-cell>
<cdk-cell *cdkCellDef="let row" class="example-cell"> {{row.id}} </cdk-cell>
</ng-container>
<!-- Progress Column -->
<ng-container cdkColumnDef="progress">
<cdk-header-cell *cdkHeaderCellDef class="example-header-cell"> Progress </cdk-header-cell>
<cdk-cell *cdkCellDef="let row" class="example-cell"> {{row.progress}}% </cdk-cell>
</ng-container>
<!-- Name Column -->
<ng-container cdkColumnDef="userName">
<cdk-header-cell *cdkHeaderCellDef class="example-header-cell"> Name </cdk-header-cell>
<cdk-cell *cdkCellDef="let row" class="example-cell"> {{row.name}} </cdk-cell>
</ng-container>
<cdk-header-row *cdkHeaderRowDef="displayedColumns" class="example-header-row"></cdk-header-row>
<cdk-row *cdkRowDef="let row; columns: displayedColumns;" class="example-row"></cdk-row>
</cdk-table>
</div>
The rest of implementations, search, menus, checkboxes, etc, is your responsibility to implement the logic for manipulating the information.
Use the documentation about cdk-table for more details:
https://material.angular.io/guide/cdk-table
Result:
Do me saber and achievement, I understand my explanation, and I apologize for my English. I am learning.