Maison  >  Article  >  interface Web  >  Maîtriser les colonnes redimensionnables dans une table angulaire : un guide étape par étape pour les développeurs

Maîtriser les colonnes redimensionnables dans une table angulaire : un guide étape par étape pour les développeurs

Susan Sarandon
Susan Sarandonoriginal
2024-10-15 22:38:02788parcourir

Mastering Resizable Columns in Angular Table: A Step-by-Step Guide for Developers

Comment créer des colonnes redimensionnables dans une table angulaire : un guide étape par étape

Les tableaux de matériaux angulaires offrent un moyen élégant d'afficher les données. Cependant, les utilisateurs souhaitent souvent des fonctionnalités supplémentaires, telles que la possibilité de redimensionner les colonnes du tableau pour un meilleur contrôle sur l'affichage des données. Dans ce guide, nous passerons en revue le processus de création de colonnes redimensionnables dans une table angulaire à l'aide d'une directive personnalisée. Vous apprendrez comment configurer la directive, styliser le redimensionneur et implémenter le redimensionnement des colonnes étape par étape.

Introduction

L'ajout de colonnes redimensionnables à une table Angular Material implique la création d'une directive personnalisée qui écoute les événements de la souris, permettant aux utilisateurs de cliquer et de faire glisser une colonne pour ajuster sa largeur. Cela donne aux utilisateurs une flexibilité, en particulier lorsqu'ils traitent de grands ensembles de données, améliorant ainsi l'expérience utilisateur.

Dans ce tutoriel, nous allons :

  • Créez une directive de redimensionnement de colonne personnalisée.
  • Gérez les événements de la souris pour redimensionner les colonnes.
  • Appliquez des styles pour une expérience utilisateur fluide.
  • Attachez la directive à une table de matériaux angulaires.

Plongeons-y.

Étape 1 : Configuration de la table des matériaux angulaires

Tout d’abord, assurez-vous que Angular Material est installé sur votre projet Angular. Sinon, exécutez la commande suivante pour ajouter du matériau angulaire à votre projet :

ng add @angular/material

Une fois Angular Material installé, vous pouvez créer une table de base en utilisant le code suivant.

HTML pour le tableau :

<div class="resizable-table">
  <table mat-table [dataSource]="dataSource">
    <ng-container *ngFor="let column of displayedColumns" [matColumnDef]="column">
      <th mat-header-cell *matHeaderCellDef appColumnResize>{{ column }}</th>
      <td mat-cell *matCellDef="let element">{{ element[column] }}</td>
    </ng-container>
    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
  </table>
</div>

Ici, nous utilisons mat-table d'Angular Material pour afficher un tableau simple. La directive appColumnResize est appliquée aux éléments th (en-tête) pour rendre les colonnes redimensionnables.

Données pour le tableau :

import { Component, ViewEncapsulation } from '@angular/core';

export interface PeriodicElement {
  name: string;
  position: number;
  weight: number;
  symbol: string;
}

const ELEMENT_DATA: PeriodicElement[] = [
  { position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H' },
  { position: 2, name: 'Helium', weight: 4.0026, symbol: 'He' },
  // ... add more data
];

@Component({
  selector: 'table-basic-example',
  styleUrls: ['table-basic-example.scss'],
  templateUrl: 'table-basic-example.html',
  encapsulation: ViewEncapsulation.None,
})
export class TableBasicExample {
  displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
  dataSource = ELEMENT_DATA;
}

Le composant comprend des données pour les éléments périodiques, que nous afficherons dans le tableau.

Étape 2 : Création de la directive de redimensionnement des colonnes

Ensuite, nous implémenterons une directive Angular personnalisée qui active la fonctionnalité de redimensionnement des colonnes du tableau.

Mise en œuvre de la directive :

import {
  Directive,
  ElementRef,
  Renderer2,
  NgZone,
  Input,
  OnInit,
  OnDestroy,
} from '@angular/core';
import { fromEvent, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

@Directive({
  selector: '[appColumnResize]',
})
export class ColumnResizeDirective implements OnInit, OnDestroy {
  @Input() resizableTable: HTMLElement | null = null;

  private startX!: number;
  private startWidth!: number;
  private isResizing = false;
  private column: HTMLElement;
  private resizer!: HTMLElement;
  private destroy$ = new Subject<void>();

  constructor(
    private el: ElementRef,
    private renderer: Renderer2,
    private zone: NgZone
  ) {
    this.column = this.el.nativeElement;
  }

  ngOnInit() {
    this.createResizer();
    this.initializeResizeListener();
  }

  private createResizer() {
    this.resizer = this.renderer.createElement('div');
    this.renderer.addClass(this.resizer, 'column-resizer');
    this.renderer.setStyle(this.resizer, 'position', 'absolute');
    this.renderer.setStyle(this.resizer, 'right', '0');
    this.renderer.setStyle(this.resizer, 'top', '0');
    this.renderer.setStyle(this.resizer, 'width', '5px');
    this.renderer.setStyle(this.resizer, 'cursor', 'col-resize');
    this.renderer.appendChild(this.column, this.resizer);
  }

  private initializeResizeListener() {
    this.zone.runOutsideAngular(() => {
      fromEvent(this.resizer, 'mousedown')
        .pipe(takeUntil(this.destroy$))
        .subscribe((event: MouseEvent) => this.onMouseDown(event));

      fromEvent(document, 'mousemove')
        .pipe(takeUntil(this.destroy$))
        .subscribe((event: MouseEvent) => this.onMouseMove(event));

      fromEvent(document, 'mouseup')
        .pipe(takeUntil(this.destroy$))
        .subscribe(() => this.onMouseUp());
    });
  }

  private onMouseDown(event: MouseEvent) {
    event.preventDefault();
    this.isResizing = true;
    this.startX = event.pageX;
    this.startWidth = this.column.offsetWidth;
  }

  private onMouseMove(event: MouseEvent) {
    if (!this.isResizing) return;
    const width = this.startWidth + (event.pageX - this.startX);
    this.renderer.setStyle(this.column, 'width', `${width}px`);
  }

  private onMouseUp() {
    if (!this.isResizing) return;
    this.isResizing = false;
  }

  ngOnDestroy() {
    this.destroy$.next();
    this.destroy$.complete();
  }
}

Explication:

  • createResizer() : ajoute un élément de redimensionnement (div) à l'en-tête de colonne.
  • onMouseDown() : déclenché lorsque l'utilisateur clique sur le redimensionneur, enregistrant la position initiale.
  • onMouseMove() : met à jour la largeur de la colonne lorsque l'utilisateur fait glisser le redimensionneur.
  • onMouseUp() : termine le redimensionnement lorsque l'utilisateur relâche le bouton de la souris.

Étape 3 : Styliser le redimensionneur

Nous devons styliser le redimensionneur pour que les utilisateurs sachent qu'il peut être déplacé. Ajoutez le CSS suivant à vos styles :

.resizable-table {
  th {
    position: relative;

    .column-resizer {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      width: 10px;
      cursor: col-resize;
      z-index: 1;

      &:hover {
        border-right: 2px solid red;
      }
    }

    &.resizing {
      user-select: none;
    }
  }

  &.resizing {
    cursor: col-resize;
    user-select: none;
  }
}

Ce CSS positionne correctement le redimensionneur, ajoute un effet de survol et modifie le curseur pour indiquer le redimensionnement.

Étape 4 : tester la table

Maintenant que la directive et les styles sont en place, essayez de redimensionner les colonnes. Vous devriez pouvoir cliquer sur le redimensionneur, le faire glisser vers la gauche ou la droite et ajuster dynamiquement la largeur de chaque colonne.

FAQ

Q : Que se passe-t-il si le tableau redimensionnable est trop large ?

R : La table débordera et s'ajustera en fonction de la largeur du conteneur. Assurez-vous d'ajouter un comportement de défilement approprié ou des ajustements de conteneur pour gérer les grandes tables.

Q : Puis-je rendre des colonnes spécifiques non redimensionnables ?

R : Oui, vous pouvez appliquer conditionnellement la directive appColumnResize à des colonnes spécifiques uniquement en utilisant les directives structurelles intégrées d'Angular comme *ngIf.

Q : Cette approche est-elle efficace pour les grandes tables ?

R : Cette solution fonctionne bien pour les tables de taille moyenne. Cependant, pour des ensembles de données extrêmement volumineux, vous souhaiterez peut-être optimiser davantage en utilisant la stratégie de détection des changements d'Angular ou un mécanisme de défilement virtuel.

Conclusion

En suivant ce guide, vous disposez désormais d'une fonctionnalité de colonne redimensionnable entièrement fonctionnelle pour vos tables Angular Material. Cette personnalisation améliore la flexibilité et la convivialité de vos tables, offrant une meilleure expérience utilisateur. Bon codage !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn