Tablas en Angular Material

Intermedio
Angular
Angular
Actualizado: 27/08/2024

¡Desbloquea el curso completo!

IA
Ejercicios
Certificado
Entrar

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.

Progreso guardado
Asistente IA
Ejercicios
Iniciar sesión gratis

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:

  1. 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 array displayedColumns del componente.
  2. 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">.
  3. 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;">.
  4. Proporcionar los datos:
    • En el componente TypeScript, se define dataSource con los datos que se mostrarán en la tabla.

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

  1. Aprender a instalar Angular Material y Angular CDK.
  2. Entender cómo importar módulos de Angular Material.
  3. Conocer el proceso de creación de una tabla en Angular Material.
  4. 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

⭐⭐⭐⭐⭐
4.9/5 valoración