Vimos en conceptos anterior para mostrar datos en una tabla utilizamos la componente mat-table. Ahora veremos como permitir ordenar los datos por una determinada columna.
Mostrar un listado de artículos ficticios(codigo, descripción y precio), permitir mostrarlos en forma ordenada por cualquiera de los tres campos.
Crearemos primero el proyecto
ng new proyecto029
Procedemos a instalar todas las dependencias de Angular Material ayudados por Angular CLI mediante el comando 'add':
ng add @angular/material
Modificamos el archivo 'app.module.ts' donde debemos importar MatTableModule y MatSortModule:
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { MatTableModule } from '@angular/material/table'; import { MatSortModule } from '@angular/material/sort'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, BrowserAnimationsModule, MatTableModule, MatSortModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Modificamos el archivo 'app.component.ts' con la lógica de nuestra componente:
import { Component, ViewChild } from '@angular/core'; import { MatTableDataSource } from '@angular/material/table'; import {MatSort} from '@angular/material/sort'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { columnas: string[] = ['codigo', 'descripcion', 'precio']; datos: Articulo[] = []; dataSource:any; @ViewChild(MatSort, {static: true}) sort!: MatSort; ngOnInit() { for (let x = 1; x <= 10; x++) this.datos.push(new Articulo(x, `artículo ${x}`, Math.trunc(Math.random() * 1000))); this.dataSource = new MatTableDataSource<Articulo>(this.datos); this.dataSource.sort = this.sort; } } export class Articulo { constructor(public codigo: number, public descripcion: string, public precio: number) { } }
En este archivo importamos las clases:
import { MatTableDataSource } from '@angular/material/table'; import {MatSort} from '@angular/material/sort';
En el método ngOnInit almacenamos en el arreglo de tipo Articulo 10 elementos aleatorios:
ngOnInit() { for (let x = 1; x <= 10; x++) this.datos.push(new Articulo(x, `artículo ${x}`, Math.trunc(Math.random() * 1000)));
También en este método inicializamos la propiedad dataSource con la referencia de un objeto MatTableDataSource a la que le pasamos como parámetro en el constructor el arreglo:
this.dataSource = new MatTableDataSource<Articulo>(this.datos);
Finalmente inicializamos la propiedad 'sort' del 'dataSource' con la referencia de la componente 'sort':
this.dataSource.sort = this.sort;
La clase 'Articulo' se la declaró después de la clase 'AppComponent':
export class Articulo { constructor(public codigo: number, public descripcion: string, public precio: number) { } }
Codificamos la interfaz visual en el archivo 'app.component.html':
<div class="mat-elevation-z8"> <table mat-table [dataSource]="dataSource" class="mat-elevation-z8" matSort> <ng-container matColumnDef="codigo"> <th mat-header-cell *matHeaderCellDef mat-sort-header> Código </th> <td mat-cell *matCellDef="let articulo"> {{articulo.codigo}} </td> </ng-container> <ng-container matColumnDef="descripcion"> <th mat-header-cell *matHeaderCellDef mat-sort-header> Descripción </th> <td mat-cell *matCellDef="let articulo"> {{articulo.descripcion}} </td> </ng-container> <ng-container matColumnDef="precio"> <th mat-header-cell *matHeaderCellDef mat-sort-header> Precio </th> <td mat-cell *matCellDef="let articulo"> {{articulo.precio}} </td> </ng-container> <tr mat-header-row *matHeaderRowDef="columnas"></tr> <tr mat-row *matRowDef="let row; columns: columnas;"></tr> </table> </div>
Cuando definimos la etiqueta 'table' especificamos el enlace de la propiedad '[dataSource]' con nuestro objeto 'dataSource' y disponemos 'matSort':
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" matSort>
Para las columnas definimos etiquetas 'ng-container' iniciando la propiedad 'matColumnDef' con alguna de las componentes del atributo 'columnas', también creamos el título de la columna como su contenido, lo nuevo es agregar 'mat-sort-header' si queremos que dicha columna se pueda ordenar:
<ng-container matColumnDef="codigo"> <th mat-header-cell *matHeaderCellDef mat-sort-header> Código </th> <td mat-cell *matCellDef="let articulo"> {{articulo.codigo}} </td> </ng-container> <ng-container matColumnDef="descripcion"> <th mat-header-cell *matHeaderCellDef mat-sort-header> Descripción </th> <td mat-cell *matCellDef="let articulo"> {{articulo.descripcion}} </td> </ng-container> <ng-container matColumnDef="precio"> <th mat-header-cell *matHeaderCellDef mat-sort-header> Precio </th> <td mat-cell *matCellDef="let articulo"> {{articulo.precio}} </td> </ng-container>
la hoja de estilo de la componente 'app.component.css':
table { width: 100%; }
Si ejecutamos la aplicación tenemos como resultado:
Podemos probar esta aplicación en la web aquí.