This content originally appeared on Telerik Blogs and was authored by Dany Paredes
Angular Material is a popular library created by the Angular team. Let’s build a data grid using mat-table to see how it works.
One of the most common ways to show data in apps is using a list or table. It allows users to list, filter, sort and page through data. Angular Material is a package that gives us a list of components to create a beautiful interface using its components in our apps.
The Angular team created and supports Angular Material. It provides a set of visual components following the Material Design Guidelines that allow us to develop consistent user interfaces.
We’re going to build a data grid with Angular Material. The implementation is divided into six parts and focuses on the mat-table
directive for creating a data grid to show data; to allow sorting, filtering and pagination; and to boost
performance.
- Add Angular Material
- List data with
mat-table
- Add pagination
- Allow sorting
- Add filtering
- Boost performance
Read more about previous topics:
Add Angular Material
Let us create the project first.
ng new datagrid-with-angular-material
We install all the Angular Material dependencies helped by Angular CLI through the ng add
command. It will add and register Angular Material in the project.
ng add @angular/material
datagrid-with-angular-material>ng add @angular/material
i Using package manager: npm
√ Found compatible package version: @angular/material@14.0.3.
√ Package information loaded.
The package @angular/material@14.0.3 will be installed and executed.
Would you like to proceed? Yes
√ Packages successfully installed.
? Choose a prebuilt theme name, or "custom" for a custom theme: Indigo/Pink [ Preview:
https://material.angular.io?theme=indigo-pink ]
? Set up global Angular Material typography styles? Yes
? Include the Angular animations module? Include and enable animations
UPDATE package.json (1127 bytes)
√ Packages installed successfully.
UPDATE src/app/app.module.ts (423 bytes)
UPDATE angular.json (3380 bytes)
UPDATE src/index.html (595 bytes)
UPDATE src/styles.scss (181 bytes)
Angular Material modifies the application styles to match the Material Style Guide.
Next, modify the file app.module.ts where we must import MatTableModule
.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { MatTableModule } from '@angular/material/table';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
MatTableModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Next, we are going to list the data in the table.
List Data With mat-table
We modify the file app.component.ts
to add properties to the template and the mat-table
, declaring a ViewChild
mytable to reference the table in the template reference.
@ViewChild(MatTable) mytable: MatTable<Article>;
Create the property columns
to stores the names for each column using the matColumnDef
:
columns: string[] = ['name', position];
Next, we create the service NbaService
because it uses the httpClient
to import into the app.module
. Then we create the method and, using the httpClient, call the API.
The API returns one array of NBA players in the property data to simplify our code return of an observable of any.
In the real world, we must map the data to the interface.
name: "Alex"
id: 1
last_name: "Abrines"
position: "G"
}
]
In the app.component.ts
, we must inject the NbaService
into the constructor and declare a new property dataSource
to store the data from the nbaService.
export class AppComponent implements OnInit {
dataSource : any;;
constructor(private nbaService: NbaService) {
}
}
In the ngOnInit lifecycle, subscribe to the nbaService and set the data to the datasource.
ngOnInit(): void {
this.nbaService.getData().subscribe((data) => {
this.dataSource = data;
});
Next, declare the markup for the table with the directive mat-table
.
<table mat-table [dataSource]="datasource" class="mat-elevation-z8" #mytable>
<tr mat-header-row *matHeaderRowDef="columns"></tr>
<tr mat-row *matRowDef="let row; columns: columns;"></tr>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef >Name</th>
<td mat-cell *matCellDef="let t">{{ t.first_name }}</td>
</ng-container>
<ng-container matColumnDef="team">
<th mat-header-cell *matHeaderCellDef>Position</th>
<td mat-cell *matCellDef="let t">{{ t.position }}</td>
</ng-container>
</table>
When we define the table
tag, we specify the binding of the [dataSource]
property with datasource
defined in the class.
<table mat-table [dataSource]="datasource" class="mat-elevation-z8" #mytable>
For the columns, we define ng-container
labels by initializing the matColumnDef
property with one of the components of the columns
attribute. We also create the column title as its content:
<ng-container matColumnDef="FirstName">
<th mat-header-cell *matHeaderCellDef>Name</th>
<td mat-cell *matCellDef="let t">{{ t.first_name }}</td>
</ng-container>
More about Angular Material Table.
Add Pagination
When we display a large amount of data, one nice feature is pagination. To provide the pagination, Angular Material gives us the mat-paginator
.
First, we will import the module MatPaginatorModule
into the modules.
import { MatPaginatorModule } from '@angular/material/paginator';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
MatTableModule,
MatPaginatorModule,
],
Edit the app.component.ts and add a new property for paginator
ViewChild. To access the MatPagination from the template, update the code into the subscription and set to datasource a new instance of MatTableDataSource
with the
data from the subscription and the paginator viewchild.
@ViewChild(MatPaginator, { static: true }) paginator!: MatPaginator;
ngOnInit(): void {
this.nbaService.getData().subscribe((data) => {
this.dataSource = new MatTableDataSource<any>(data);
this.dataSource.paginator = this.paginator;
});
}
Next, update the template to connect the table with the datasource and configure the mat-paginator
with the list of options for pagination. Adding the directive showFirstLastButton
activates the navigation buttons to move from
last to first.
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" #mytable>
...
</table>
<mat-paginator [pageSizeOptions]="[3, 5, 10]" showFirstLastButtons></mat-paginator>
Add Sorting
To allow the users to sort the data, use MatSort
. First, we import the MatSortModule
in the app.module.
import { MatSortModule } from '@angular/material/sort';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
MatSortModule,
MatTableModule,
MatPaginatorModule,
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
First, add a viewchild for the paginator, import the MatSort
into the app.component.ts
, and declare a viewChild sort
to link it with the template.
import { MatSort } from '@angular/material/sort';
@ViewChild(MatSort, { static: true }) sort!: MatSort;
On the ngOnInit lifecycle, assign to the Datasource sort property MathSort viewchild
.
ngOnInit(): void {
this.nbaService.getData().subscribe((data) => {
this.dataSource = new MatTableDataSource<any>(data);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
});
}
Edit the app.component.html, add the matSort
directive to the table and add the mat-sort-header
for each column.
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" #mytable matSort>
<tr mat-header-row *matHeaderRowDef="columns" ></tr>
<tr mat-row *matRowDef="let row; columns: columns;"></tr>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Name</th>
<td mat-cell *matCellDef="let t">{{ t.first_name }}</td>
</ng-container>
<ng-container matColumnDef="team">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Position</th>
<td mat-cell *matCellDef="let t">{{ t.position }}</td>
</ng-container>
</table>
Add Filtering
Sadly Angular Material does not ship with a particular component or filter directive. To solve this problem, we must implement the data filtering manually.
We define a method called filter
that is executed each time the user enters or deletes a character in the mat-input control:
filter(event: Event) {
const filter = (event.target as HTMLInputElement).value;
this.dataSource.filter = filter.trim().toLowerCase();
}
When we initialize the filter
property of dataSource, the data displayed in the view is updated.
<input matInput (keyup)="filter($event)" placeholder="find">
Result:
Boost Performance
Sometimes we have to display an extensive list of data in a table or list. Adding all of them in the DOM can cause problems and force the application to slow down.
The Angular CDK provides a virtual scroll to display only a small subset of the items in the viewport. It keeps the number of DOM elements constant, boosting the application’s performance.
Unfortunately, the virtual scroll CDK
does not work by default with mat-table
, but the package https://github.com/diprokon/ng-table-virtual-scroll (not official) is a directive that allows the use of virtual scrolling in mat-table.
import { MatSortModule } from '@angular/material/sort';
import { ScrollingModule } from '@angular/cdk/scrolling';
import { TableVirtualScrollModule } from 'ng-table-virtual-scroll';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
MatSortModule,
MatTableModule,
MatPaginatorModule,
ScrollingModule,
TableVirtualScrollModule,
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {},
Change the MatTableDataSource to TableVirtualScrollDataSource.
this.nbaService.getData().subscribe((data) => {
this.dataSource = new TableVirtualScrollDataSource(data);
});
Note: ng-table-virtual-scroll is not the official package.
Edit the template:
<cdk-virtual-scroll-viewport
tvsItemSize="30"
headerHeight="56"
class="wrapper mat-elevation-z2"
style="height: 400px"
>
....
</cdk-virtual-scroll-viewport>
Conclusion
In this article, we had the chance to use Angular Material to build a data list. Angular Material provides a few components and directives for creating dynamic applications. However, not all the features come out of the box, and sometimes we need to add
custom solutions like filtering or using extra packages like the ng-table-virtual-scroll
.
See the full code example for this article and play with the example app at the following links:
Next, we’ll compare this process with building a data grid using Kendo UI for Angular.
This content originally appeared on Telerik Blogs and was authored by Dany Paredes
Dany Paredes | Sciencx (2022-11-07T09:17:04+00:00) Using Angular Material To Build a Data Grid in Angular. Retrieved from https://www.scien.cx/2022/11/07/using-angular-material-to-build-a-data-grid-in-angular/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.