Angular

Angular

Tutorial Angular: Tablas en Angular Material

Angular Material tablas: creación y uso. Domina la creación y uso de tablas en Angular Material con ejemplos prácticos y detallados.

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.

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:

Certifícate en Angular con CertiDevs PLUS

Ejercicios de esta lección Tablas en Angular Material

Evalúa tus conocimientos de esta lección Tablas en Angular Material con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Signals en Angular

Angular
Puzzle

Guards funcionales

Angular
Test

Decodificar JWT en Angular

Angular
Test

Servicio con HttpClient

Angular
Código

Ciclo de vida de componentes en Angular

Angular
Test

Gestión de productos de Fake Store API

Angular
Proyecto

Data binding en Angular

Angular
Test

Routes sin módulos en Angular

Angular
Código

Router en Angular

Angular
Test

Instalación de Angular

Angular
Puzzle

Route Guards basados en interfaces

Angular
Código

La directiva @if en Angular

Angular
Puzzle

Formularios reactivos en Angular

Angular
Código

Servicios en Angular

Angular
Puzzle

Interceptor funcional

Angular
Test

Servicio con Array

Angular
Código

La directiva @for en Angular

Angular
Puzzle

Interceptores HTTP

Angular
Código

Componentes standalone true

Angular
Puzzle

Formularios con ngModel en Angular

Angular
Puzzle

Routes en Angular

Angular
Test

Comunicación entre componentes Angular

Angular
Test

Parámetros en rutas con ActivatedRoute

Angular
Test

CRUD de Restaurantes y Platos

Angular
Proyecto

Tablas en Angular Material

Angular
Puzzle

Formulario de registro de usuarios

Angular
Proyecto

Instalación y uso de NgBoostrap

Angular
Puzzle

Desarrollo de componentes Angular

Angular
Test

JWT en Angular

Angular
Código

Formularios reactivos en Angular

Angular
Puzzle

Formularios en Angular Material

Angular
Puzzle

Layout con Angular Material

Angular
Puzzle

Effects en Angular

Angular
Test

Data binding

Angular
Código

HttpClient en servicios de Angular

Angular
Puzzle

Desarrollo de módulos Angular

Angular
Puzzle

Comandos Angular CLI

Angular
Puzzle

Subir archivo en formularios

Angular
Test

La directiva routerLink en Angular

Angular
Test

Todas las lecciones de Angular

Accede a todas las lecciones de Angular y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Instalación Angular

Angular

Introducción Y Entorno

Comandos Angular Cli

Angular

Introducción Y Entorno

Desarrollo De Componentes Angular

Angular

Componentes

Data Binding En Angular

Angular

Componentes

Ciclo De Vida De Componentes En Angular

Angular

Componentes

Comunicación Entre Componentes Angular

Angular

Componentes

La Directiva @If En Angular

Angular

Componentes

La Directiva @For En Angular

Angular

Componentes

Componentes Standalone

Angular

Componentes

Desarrollo De Módulos Angular

Angular

Módulos

Routes En Angular

Angular

Enrutado Y Navegación

Router En Angular

Angular

Enrutado Y Navegación

La Directiva Routerlink En Angular

Angular

Enrutado Y Navegación

Parámetros En Rutas Con Activatedroute

Angular

Enrutado Y Navegación

Routes Sin Módulos En Angular

Angular

Enrutado Y Navegación

Servicios En Angular

Angular

Servicios E Inyección De Dependencias

Httpclient En Servicios De Angular

Angular

Servicios E Inyección De Dependencias

Formularios Con Ngmodel En Angular

Angular

Formularios

Formularios Reactivos En Angular

Angular

Formularios

Subir Archivo En Formularios

Angular

Formularios

Layout Con Angular Material

Angular

Integración Con Angular Material

Tablas En Angular Material

Angular

Integración Con Angular Material

Formularios En Angular Material

Angular

Integración Con Angular Material

Instalación Y Uso De Ngboostrap

Angular

Integración Con Bootstrap Css

Signals En Angular

Angular

Signals Y Reactividad

Effects En Angular

Angular

Signals Y Reactividad

Route Guards Basados En Interfaces

Angular

Autenticación Y Autorización

Guards Funcionales

Angular

Autenticación Y Autorización

Interceptores Http Basados En Interfaz

Angular

Autenticación Y Autorización

Interceptores Http Funcionales

Angular

Autenticación Y Autorización

Seguridad Jwt En Angular

Angular

Autenticación Y Autorización

Decodificar Tokens Jwt En Angular

Angular

Autenticación Y Autorización

Certificados de superación de Angular

Supera todos los ejercicios de programación del curso de Angular y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.

En esta lección

Objetivos de aprendizaje 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.