Las tablas en Angular Material proporcionan una manera de mostrar datos en una cuadrícula con columnas y filas. Estas tablas se integran a la perfección con los demás componentes de Angular Material y ofrecen capacidades avanzadas como paginación, ordenación y filtrado.
¿Te está gustando esta lección?
Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.
Más de 25.000 desarrolladores ya confían en CertiDevs
Prerrequisitos
Es esencial tener un proyecto Angular configurado.
Antes de utilizar el componente de tabla de Angular Material, es necesario ejecutar el siguiente comando para instalar Angular Material y Angular CDK (Component Dev Kit) en un proyecto Angular:
ng add @angular/material
Este comando también configura automáticamente el archivo angular.json
y agrega las fuentes y estilos necesarios a la aplicación.
Importar módulos de Angular Material
En módulos tradicionales
Es necesario importar el módulo MatTableModule
en el módulo donde se utilizará la tabla:
import { MatTableModule } from '@angular/material/table';
@NgModule({
imports: [
MatTableModule
],
})
export class AppModule { }
En componentes standalone
Para componentes standalone, puedes importar los módulos necesarios directamente en el decorador @Component
:
import { Component } from '@angular/core';
import { MatTableModule } from '@angular/material/table';
@Component({
selector: 'app-my-table',
standalone: true,
imports: [MatTableModule],
templateUrl: './my-table.component.html',
styleUrls: ['./my-table.component.css']
})
export class MyTableComponent {
// ... lógica del componente
}
Ejemplo de tabla en Angular Material
Para utilizar la tabla en Angular Material, se deben seguir estos pasos:
- Definir las columnas:
- Se define un conjunto de columnas utilizando
matColumnDef
dentro de elementos<ng-container>
. - Cada
matColumnDef
corresponde a una columna y debe coincidir con una entrada en el arraydisplayedColumns
del componente.
- Se define un conjunto de columnas utilizando
- Definir el contenido de las columnas:
- Para cada columna, se define:
- El encabezado usando
<th mat-header-cell *matHeaderCellDef>
. - Las celdas de datos usando
<td mat-cell *matCellDef="let element">
.
- El encabezado usando
- Para cada columna, se define:
- Estructurar la tabla:
- Se usa
<table mat-table>
como contenedor principal. - Se definen las filas de encabezado con
<tr mat-header-row *matHeaderRowDef="displayedColumns">
. - Se definen las filas de datos con
<tr mat-row *matRowDef="let row; columns: displayedColumns;">
.
- Se usa
- Proporcionar los datos:
- En el componente TypeScript, se define
dataSource
con los datos que se mostrarán en la tabla.
- En el componente TypeScript, se define
El código TypeScript podría verse algo así:
import { Component } from '@angular/core';
import { MatTableModule } from '@angular/material/table';
@Component({
selector: 'app-root',
standalone: true,
imports: [MatTableModule],
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
dataSource = ELEMENT_DATA;
}
const ELEMENT_DATA = [
{position: 1, name: 'Hidrógeno', weight: 1.0079, symbol: 'H'},
{position: 2, name: 'Helio', weight: 4.0026, symbol: 'He'},
{position: 3, name: 'Litio', weight: 6.941, symbol: 'Li'},
{position: 4, name: 'Berilio', weight: 9.0122, symbol: 'Be'},
{position: 5, name: 'Boro', weight: 10.811, symbol: 'B'},
{position: 6, name: 'Carbono', weight: 12.0107, symbol: 'C'},
{position: 7, name: 'Nitrógeno', weight: 14.0067, symbol: 'N'},
{position: 8, name: 'Oxígeno', weight: 15.9994, symbol: 'O'},
{position: 9, name: 'Flúor', weight: 18.9984, symbol: 'F'},
{position: 10, name: 'Neón', weight: 20.1797, symbol: 'Ne'}
];
La plantilla HTML asociada podría verse de la siguiente manera:
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<!-- Columna de Posición -->
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef> No. </th>
<td mat-cell *matCellDef="let element"> {{element.position}} </td>
</ng-container>
<!-- Columna de Nombre -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> Nombre </th>
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
</ng-container>
<!-- Columna de Peso -->
<ng-container matColumnDef="weight">
<th mat-header-cell *matHeaderCellDef> Peso </th>
<td mat-cell *matCellDef="let element"> {{element.weight}} </td>
</ng-container>
<!-- Columna de Símbolo -->
<ng-container matColumnDef="symbol">
<th mat-header-cell *matHeaderCellDef> Símbolo </th>
<td mat-cell *matCellDef="let element"> {{element.symbol}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
Este ejemplo se vería así en el navegador:
Funcionalidades adicionales
Paginación
Para agregar paginación, es necesario importar MatPaginatorModule
y añadir <mat-paginator>
en la plantilla HTML. Además, se debe configurar en el componente TypeScript.
import { MatPaginatorModule } from '@angular/material/paginator';
// En el componente
@ViewChild(MatPaginator) paginator!: MatPaginator;
ngAfterViewInit() {
this.dataSource.paginator = this.paginator;
}
<mat-paginator [pageSizeOptions]="[5, 10, 20]"
showFirstLastButtons
aria-label="Seleccionar página de elementos">
</mat-paginator>
Ordenamiento
Si se requiere ordenar las columnas, se importa MatSortModule
y se añade el atributo matSort
en el elemento <table mat-table>
.
Cada columna que se pueda ordenar debe tener el atributo mat-sort-header
.
import { MatSortModule } from '@angular/material/sort';
// En el componente
@ViewChild(MatSort) sort!: MatSort;
ngAfterViewInit() {
this.dataSource.sort = this.sort;
}
<table mat-table [dataSource]="dataSource" matSort>
<!-- ... -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Nombre </th>
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
</ng-container>
<!-- ... -->
</table>
Filtros
Se puede añadir un filtro de búsqueda utilizando el método filter
del MatTableDataSource
. Este método se puede vincular a un campo de entrada para actualizar el filtro en tiempo real.
import { MatTableDataSource } from '@angular/material/table';
// En el componente
dataSource = new MatTableDataSource(ELEMENT_DATA);
applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
this.dataSource.filter = filterValue.trim().toLowerCase();
if (this.dataSource.paginator) {
this.dataSource.paginator.firstPage();
}
}
<mat-form-field>
<mat-label>Filtro</mat-label>
<input matInput (keyup)="applyFilter($event)" placeholder="Ex. ium" #input>
</mat-form-field>
Ejemplo completo
Aquí tienes un ejemplo completo que incluye todas las funcionalidades antes mencionadas:
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatTableModule, MatTableDataSource } from '@angular/material/table';
import { MatPaginatorModule, MatPaginator } from '@angular/material/paginator';
import { MatSortModule, MatSort } from '@angular/material/sort';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
export interface PeriodicElement {
position: number;
name: string;
weight: number;
symbol: string;
group: number;
period: number;
}
@Component({
selector: 'app-element-table',
standalone: true,
imports: [
CommonModule,
MatTableModule,
MatPaginatorModule,
MatSortModule,
MatFormFieldModule,
MatInputModule],
templateUrl: './element-table.component.html',
styleUrls: ['./element-table.component.css']
})
export class ElementTableComponent implements AfterViewInit {
displayedColumns: string[] = ['position', 'name', 'weight', 'symbol', 'group', 'period'];
dataSource = new MatTableDataSource<PeriodicElement>(ELEMENT_DATA);
@ViewChild(MatPaginator) paginator!: MatPaginator;
@ViewChild(MatSort) sort!: MatSort;
ngAfterViewInit() {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
this.dataSource.filter = filterValue.trim().toLowerCase();
if (this.dataSource.paginator) {
this.dataSource.paginator.firstPage();
}
}
}
const ELEMENT_DATA = [
{position: 1, name: 'Hidrógeno', weight: 1.0079, symbol: 'H', group: 1, period: 1},
{position: 2, name: 'Helio', weight: 4.0026, symbol: 'He', group: 18, period: 1},
{position: 3, name: 'Litio', weight: 6.941, symbol: 'Li', group: 1, period: 2},
{position: 4, name: 'Berilio', weight: 9.0122, symbol: 'Be', group: 2, period: 2},
{position: 5, name: 'Boro', weight: 10.811, symbol: 'B', group: 13, period: 2},
{position: 6, name: 'Carbono', weight: 12.0107, symbol: 'C', group: 14, period: 2},
{position: 7, name: 'Nitrógeno', weight: 14.0067, symbol: 'N', group: 15, period: 2},
{position: 8, name: 'Oxígeno', weight: 15.9994, symbol: 'O', group: 16, period: 2},
{position: 9, name: 'Flúor', weight: 18.9984, symbol: 'F', group: 17, period: 2},
{position: 10, name: 'Neón', weight: 20.1797, symbol: 'Ne', group: 18, period: 2},
{position: 11, name: 'Sodio', weight: 22.9897, symbol: 'Na', group: 1, period: 3},
{position: 12, name: 'Magnesio', weight: 24.305, symbol: 'Mg', group: 2, period: 3},
{position: 13, name: 'Aluminio', weight: 26.9815, symbol: 'Al', group: 13, period: 3},
{position: 14, name: 'Silicio', weight: 28.0855, symbol: 'Si', group: 14, period: 3},
{position: 15, name: 'Fósforo', weight: 30.9738, symbol: 'P', group: 15, period: 3}
];
<div class="table-container">
<mat-form-field>
<mat-label>Filtro</mat-label>
<input matInput (keyup)="applyFilter($event)" placeholder="elemento" #input>
</mat-form-field>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef> No. </th>
<td mat-cell *matCellDef="let element"> {{element.position}} </td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> Nombre </th>
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
</ng-container>
<ng-container matColumnDef="weight">
<th mat-header-cell *matHeaderCellDef> Peso </th>
<td mat-cell *matCellDef="let element"> {{element.weight}} </td>
</ng-container>
<ng-container matColumnDef="symbol">
<th mat-header-cell *matHeaderCellDef> Símbolo </th>
<td mat-cell *matCellDef="let element"> {{element.symbol}} </td>
</ng-container>
<ng-container matColumnDef="group">
<th mat-header-cell *matHeaderCellDef> Grupo </th>
<td mat-cell *matCellDef="let element"> {{element.group}} </td>
</ng-container>
<ng-container matColumnDef="period">
<th mat-header-cell *matHeaderCellDef> Período </th>
<td mat-cell *matCellDef="let element"> {{element.period}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator class="paginator" [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons
aria-label="Seleccionar página de elementos">
</mat-paginator>
</div>
Así se vería en el navegador:
Aprendizajes de esta lección
- Aprender a instalar Angular Material y Angular CDK.
- Entender cómo importar módulos de Angular Material.
- Conocer el proceso de creación de una tabla en Angular Material.
- Aplicar funcionalidades adicionales a la tabla.
Completa Angular y certifícate
Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.
Asistente IA
Resuelve dudas al instante
Ejercicios
Practica con proyectos reales
Certificados
Valida tus conocimientos
Más de 25.000 desarrolladores ya se han certificado con CertiDevs