”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 掌握 Angular Table 中可调整大小的列:开发人员分步指南

掌握 Angular Table 中可调整大小的列:开发人员分步指南

发布于2024-11-08
浏览:622

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

如何在 Angular 表中创建可调整大小的列:分步指南

Angular Material 表提供了一种时尚的数据显示方式。然而,用户通常需要额外的功能,例如调整表列大小以更好地控制数据显示的能力。在本指南中,我们将逐步介绍使用自定义指令在 Angular 表中创建可调整大小的列的过程。您将学习如何设置指令、调整大小的样式以及逐步实施列大小调整。

介绍

向 Angular Material 表添加可调整大小的列涉及创建侦听鼠标事件的自定义指令,允许用户单击并拖动列以调整其宽度。这为用户提供了灵活性,特别是在处理大型数据集时,改善了用户体验。

在本教程中,我们将:

  • 创建自定义列调整大小指令。
  • 处理鼠标事件以调整列大小。
  • 应用样式以获得流畅的用户体验。
  • 将指令附加到 Angular Material 表。

让我们深入探讨一下。

第 1 步:设置角度材质表

首先,确保您的 Angular 项目安装了 Angular Material。如果没有,请运行以下命令将 Angular Material 添加到您的项目中:

ng add @angular/material

安装 Angular Material 后,您可以使用以下代码创建基本表格。

表格的 HTML:

{{ column }} {{ element[column] }}

在这里,我们使用 Angular Material 中的 mat-table 来显示一个简单的表格。 appColumnResize 指令应用于 th(标题)元素以使列可调整大小。

表格数据:

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;
}

该组件包含周期性元素的数据,我们将在表中显示这些数据。

第 2 步:创建列调整大小指令

接下来,我们将实现一个自定义 Angular 指令,该指令支持调整表列大小的功能。

指令实施:

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();

  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();
  }
}

解释:

  • createResizer():将调整器元素 (div) 添加到列标题。
  • onMouseDown():当用户点击缩放器时触发,记录初始位置。
  • onMouseMove():当用户拖动缩放器时更新列宽。
  • onMouseUp():当用户释放鼠标按钮时结束调整大小。

第 3 步:调整大小调整器的样式

我们需要设置调整大小的样式,以便用户知道它是可拖动的。将以下 CSS 添加到您的样式中:

.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;
  }
}

此 CSS 正确定位调整大小,添加悬停效果,并更改光标以指示可调整大小。

第 4 步:测试表

既然指令和样式都已就位,请尝试调整列的大小。您应该能够单击调整器,向左或向右拖动它,并动态调整每列的宽度。

常见问题解答

问:如果可调整大小的表格太宽会发生什么?

A:表格会溢出并根据容器的宽度进行调整。确保添加适当的滚动行为或容器调整来处理大型表格。

问:我可以使特定列不可调整大小吗?

答:是的,您可以使用 Angular 的内置结构指令(例如 *ngIf.

)有条件地将 appColumnResize 指令仅应用于特定列

问:这种方法对于大型表来说性能友好吗?

答:此解决方案适用于中等大小的桌子。然而,对于非常大的数据集,您可能希望通过使用 Angular 的更改检测策略或虚拟滚动机制来进一步优化。

结论

通过遵循本指南,您现在可以为 Angular Material 表提供功能齐全的可调整大小的列功能。这种自定义增强了表格的灵活性和可用性,提供更好的用户体验。快乐编码!

版本声明 本文转载于:https://dev.to/chintanonweb/mastering-resizable-columns-in-angular-table-a-step-by-step-guide-for-developers-4f5n?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何测试 Cron 作业:完整指南
    如何测试 Cron 作业:完整指南
    Cron 作业在许多系统中对于调度任务、自动化流程和按指定时间间隔运行脚本至关重要。无论您是维护 Web 服务器、自动备份还是运行例行数据导入,cron 作业都能让您的操作顺利运行。但与任何自动化任务一样,它们必须经过彻底测试以确保可靠性和准确性。 在本文中,我们将探讨如何有效地测试 cron 作...
    编程 发布于2024-11-08
  • Next.js 中间件简介:它如何工作并提供示例
    Next.js 中间件简介:它如何工作并提供示例
    我们来谈谈Nextjs中的路由。今天,我们来谈谈最强大的事物中间件之一。 Nextjs 中的中间件提供了一种强大而灵活的方法来拦截来自服务器的请求并控制请求流(重定向、URL 重写)并全局增强身份验证、标头、cookie 持久性等功能。 创建中间件 让我们创建 Middleware ...
    编程 发布于2024-11-08
  • 道具基础知识:第 1 部分
    道具基础知识:第 1 部分
    这是一个关于如何使用道具的初学者友好教程。在阅读之前了解什么是解构以及如何使用/创建组件非常重要。 Props,properties的缩写,props允许我们从父组件向子组件发送信息,还需要注意的是它们可以是任何数据类型。 必须了解为任何组件创建 prop 的语法。在 React 中,您必须使用...
    编程 发布于2024-11-08
  • Hibernate 与 Spring Boot 有何不同?
    Hibernate 与 Spring Boot 有何不同?
    Hibernate 与 Spring Boot 有何不同? Hibernate 和 Spring Boot 都是 Java 生态系统中流行的框架,但它们有不同的用途并具有不同的功能。 休眠 Hibernate 是一个对象关系映射 (ORM) 框架,它允许开发人员使用...
    编程 发布于2024-11-08
  • C++ 如何处理十进制数据类型?
    C++ 如何处理十进制数据类型?
    C 中的十进制数据类型 C 提供了各种数据类型来处理数值,但令人惊讶的是,十进制数据类型本身并不支持。在处理精确的十进制值或与使用十进制格式的系统交互时,这可能是一个限制。实现选项虽然 C 不提供内置十进制类型,但有两种与他们合作的方法:1。 C Decimal TR 扩展:某些编译器(例如 gcc...
    编程 发布于2024-11-08
  • 为什么我的 Python 中的凯撒密码函数只显示最后一个移位的字符?
    为什么我的 Python 中的凯撒密码函数只显示最后一个移位的字符?
    Python 中的凯撒密码函数:加密字符串在 Python 中实现凯撒密码函数时,会出现一个常见问题,即最终的加密文本仅显示最后移动的字符。要解决此问题,有必要了解导致此行为的问题。在提供的代码中,循环迭代明文中的每个字符。对于字母字符,它根据提供的移位值来移位字符的 ASCII 代码。但是,每个移...
    编程 发布于2024-11-08
  • 4 快速​​部署PHP
    4 快速​​部署PHP
    Servbay 已成为轻松配置开发环境的首要工具。在本指南中,我们将演示如何快速、安全地部署 PHP 8.2,强调 Servbay 致力于简化部署过程。 先决条件 开始之前,请确保您的设备上安装了 Servbay。您可以直接从Servbay官方网站下载。安装直观;只需按照提示操作,就...
    编程 发布于2024-11-08
  • AngularJS 指令中的 Replace 属性何时被弃用?
    AngularJS 指令中的 Replace 属性何时被弃用?
    为什么 AngularJS 已弃用指令中的替换属性AngularJS 指令中的替换属性由于其复杂性和更好的出现而被弃用替代方案。根据官方 AngularJS API 文档,在未来的版本中它将默认为 false。弃用的原因AngularJS 团队发现了替换属性的几个问题:困难的语义: 它导致了属性合并...
    编程 发布于2024-11-08
  • 释放 Claude AI:用于经济实惠且灵活的 AI 集成的非官方 API
    释放 Claude AI:用于经济实惠且灵活的 AI 集成的非官方 API
    由 Anthropic 开发的 Claude AI 以其令人印象深刻的能力在人工智能界掀起了波澜。然而,官方 API 对于许多开发人员和小型企业来说可能过于昂贵。这就是我们的非官方 Claude AI API 的用武之地,它提供了一个更实惠、更灵活的解决方案,将 Claude 的力量集成到您的项目中...
    编程 发布于2024-11-08
  • 如何使用时间包确定 Go 中一个月的最后一天?
    如何使用时间包确定 Go 中一个月的最后一天?
    使用 Time.Time 确定给定月份的最后一天处理基于时间的数据时,通常需要确定指定月份的最后一天。无论该月有 28 天、29 天(闰年)还是 30 天或 31 天,这都会使这成为一项具有挑战性的任务。时间包解决方案Go 时间包其日期函数提供了一个方便的解决方案。 Date 的语法为:func D...
    编程 发布于2024-11-08
  • 如何在不支持的浏览器中实现“背景滤镜”效果?
    如何在不支持的浏览器中实现“背景滤镜”效果?
    CSS:为不可用的背景过滤器提供替代方案CSS 中的背景过滤器功能在大多数现代浏览器中仍然无法访问。虽然我们预计其未来的支持,但发现替代解决方案势在必行。实现类似效果的一种方法是采用具有微妙透明度的背景。下面的 CSS 代码演示了这种方法:/* Slightly transparent fallba...
    编程 发布于2024-11-08
  • Python 的 len() 函数对于不同的数据结构有多高效?
    Python 的 len() 函数对于不同的数据结构有多高效?
    理解Python内置数据结构中len()函数的成本Python中内置len()函数是确定各种数据结构长度的重要工具。它的效率至关重要,尤其是在处理大型数据集时。本文深入研究了 len() 对于不同内置数据类型(例如列表、元组、字符串和字典)的计算成本。O(1) 跨内置类型的复杂性关键要点是 len(...
    编程 发布于2024-11-08
  • 如何在 Python 中访问 Windows 剪贴板文本?
    如何在 Python 中访问 Windows 剪贴板文本?
    在 Python 中访问 Windows 剪贴板文本从 Windows 剪贴板检索文本是编程中的常见任务。本文探讨了如何使用 Python 的 win32clipboard 模块来实现此目的。pywin32 和 win32clipboardwin32clipboard 模块是 pywin32 的一部...
    编程 发布于2024-11-08
  • 如何修复 CentOS 5 上由于文件权限问题导致的 Nginx 403 Forbidden 错误?
    如何修复 CentOS 5 上由于文件权限问题导致的 Nginx 403 Forbidden 错误?
    Nginx 403 Forbidden:文件访问权限故障排除当在 Nginx 中遇到令人沮丧的“403禁止”错误时,确定根本原因可以是一个挑战。此错误通常表示对文件或目录的访问被拒绝。在该特定场景中,用户在 CentOS 5 上使用 PHP-FPM 配置了 Nginx,但无法提供指定源目录中的任何文...
    编程 发布于2024-11-08
  • React 中的函数和类组件与 TypeScript
    React 中的函数和类组件与 TypeScript
    在使用 TypeScript 的 React 中,我们可以使用两种主要方法来创建组件:功能组件和类组件。两种方法都允许使用 props 和 state,但使用的范例略有不同。 TypeScript 通过提供静态类型进一步增强了开发安全性,这使我们能够精确定义 props 和 state 的形状。 ...
    编程 发布于2024-11-08

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3