0

0

Angular数据列表多字段过滤功能的开发实践

碧海醫心

碧海醫心

发布时间:2025-11-20 20:46:01

|

715人浏览过

|

来源于php中文网

原创

Angular数据列表多字段过滤功能的开发实践

本教程详细介绍了如何在angular项目中实现数据列表的多字段模糊搜索功能。通过优化现有的单字段过滤逻辑,我们将展示如何利用`array.prototype.filter`结合逻辑或操作符,同时对用户列表的姓名、姓氏、用户名和邮箱等多个字段进行高效、大小写不敏感的过滤,从而显著提升用户体验和数据检索的灵活性。

在Angular应用开发中,数据列表的过滤功能是常见的需求。通常,用户希望能够通过输入一个关键词,在多个数据字段中进行模糊匹配,以快速定位所需信息。本文将指导您如何将一个仅支持单字段(如姓氏)过滤的功能扩展为支持多字段(如姓名、姓氏、用户名、邮箱)的灵活搜索。

1. 了解现有过滤机制

在原始实现中,过滤功能仅针对用户的lastName字段:

HTML 模板 (片段):

<input type="text" [(ngModel)]="lastname" (input)="Search()"/>
<!-- ... mat-table ... -->

TypeScript 组件逻辑 (片段):

export class GerenciamentoUsuariosListaComponent implements OnInit {
  @Input() usuarios: any[] = []; // 当前显示的用户列表
  _allUsuarios: any[] = []; // 用于存储原始、完整的用户列表
  lastname: string = ''; // 旧的搜索字段名,我们将用更通用的 searchTerm 替换

  // ... constructor, ngOnInit, refreshListUser1 ...

  Search(){
    if(this.lastname != ""){
      this.usuarios = this.usuarios.filter(res =>{
        return res.lastName.toLocaleLowerCase().match(this.lastname.toLocaleLowerCase());
      })
    }else if(this.lastname == ""){
      // 原始实现中这里会调用 ngOnInit() 重新获取数据,这并非最佳实践。
      // 更好的方式是从 _allUsuarios 恢复数据。
      this.ngOnInit();
    }
  }
}

上述代码存在两个主要问题:

  1. 只过滤了lastName一个字段。
  2. 当搜索框为空时,调用ngOnInit()会重新发起网络请求,这在大多数情况下是不必要的,且效率低下。

2. 优化组件数据管理

为了实现多字段过滤并避免不必要的网络请求,我们需要在组件中维护两份用户列表:一份是完整的原始数据,另一份是用于显示和过滤的数据。

  1. 引入 _allUsuarios 存储原始数据: 在组件类中声明一个私有变量 _allUsuarios 来保存从服务获取到的全部用户数据。

  2. 修改 refreshListUser1() 方法: 当数据从服务加载完成后,将数据同时赋值给 _allUsuarios 和 usuarios。usuarios 将是我们在模板中绑定的显示列表。

  3. 使用通用搜索词 searchTerm: 将 lastname 变量重命名为更具通用性的 searchTerm,以反映它现在可以匹配多个字段。

更新后的组件变量和数据加载:

import { Component, OnInit, Input } from '@angular/core';
import { GerenciamentoUsuariosService } from './gerenciamento-usuarios.service'; // 假设服务路径

export class GerenciamentoUsuariosListaComponent implements OnInit {
  @Input() usuarios: any[] = []; // 用于在模板中显示和过滤的用户列表
  _allUsuarios: any[] = []; // 存储从服务获取的完整用户列表
  searchTerm: string = ''; // 通用搜索关键词

  readonly displayedColumns = ['firstName', 'lastName', 'username', 'email', 'actions'];

  constructor(private service: GerenciamentoUsuariosService) {}

  ngOnInit(): void {
    this.refreshListUser1();
  }

  refreshListUser1() {
    this.service.list().subscribe(
      resp => {
        this._allUsuarios = resp.content; // 将完整数据存储到 _allUsuarios
        this.usuarios = [...this._allUsuarios]; // 初始化显示列表为完整列表
        console.log(this.usuarios);
      }
    );
  }

  // ... Search() 方法将在下一步中更新
}

3. 实现多字段过滤逻辑

核心的改变在于 Search() 方法。我们将使用 Array.prototype.filter() 结合逻辑或 (||) 操作符来检查多个字段是否包含搜索关键词。

CreateWise AI
CreateWise AI

为播客创作者设计的AI创作工具,AI自动去口癖、提交亮点和生成Show notes、标题等

下载

更新后的 Search() 方法:

// ... (组件的其他部分保持不变)

  Search() {
    // 检查搜索关键词是否为空或只包含空白字符
    if (this.searchTerm.trim() !== "") {
      const keyword = this.searchTerm.toLocaleLowerCase().trim(); // 转换为小写并去除首尾空格

      this.usuarios = this._allUsuarios.filter(res => {
        // 对每个字段进行大小写不敏感的模糊匹配,使用 || 连接多个条件
        return res.firstName.toLocaleLowerCase().includes(keyword) ||
               res.lastName.toLocaleLowerCase().includes(keyword) ||
               res.username.toLocaleLowerCase().includes(keyword) ||
               res.email.toLocaleLowerCase().includes(keyword);
      });
    } else {
      // 如果搜索关键词为空,则将显示列表重置为完整的原始列表
      this.usuarios = [...this._allUsuarios];
    }
  }
}

4. 更新 HTML 模板

最后,将 HTML 模板中的 [(ngModel)] 绑定从 lastname 更新为新的 searchTerm。

更新后的 HTML 模板 (片段):

<input type="text" [(ngModel)]="searchTerm" (input)="Search()"/>

<mat-table [dataSource]="usuarios">
    <!-- Name Column -->
    <ng-container matColumnDef="firstName">
      <mat-header-cell *matHeaderCellDef> Nome </mat-header-cell>
      <mat-cell *matCellDef="let element">{{ element.firstName }}</mat-cell>
    </ng-container>
    <!-- Last Name Column -->
    <ng-container matColumnDef="lastName">
      <mat-header-cell *matHeaderCellDef>Sobrenome</mat-header-cell>
      <mat-cell *matCellDef="let element">{{ element.lastName }}</mat-cell>
    </ng-container>
    <!-- UserName Column -->
    <ng-container matColumnDef="username">
        <mat-header-cell *matHeaderCellDef>Username</mat-header-cell>
        <mat-cell *matCellDef="let element">{{ element.username }}</mat-cell>
      </ng-container>
      <!-- Email Column -->
      <ng-container matColumnDef="email">
        <mat-header-cell *matHeaderCellDef>E-mail</mat-header-cell>
        <mat-cell *matCellDef="let element">{{ element.email }}</mat-cell>
      </ng-container>
      <!-- ... 其他列和操作 ... -->
</mat-table>

5. 完整代码示例

gerenciamento-usuarios-lista.component.html

<input type="text" [(ngModel)]="searchTerm" (input)="Search()"/>

<mat-table [dataSource]="usuarios">
    <!-- Name Column -->
    <ng-container matColumnDef="firstName">
      <mat-header-cell *matHeaderCellDef> Nome </mat-header-cell>
      <mat-cell *matCellDef="let element">{{ element.firstName }}</mat-cell>
    </ng-container>
    <!-- Last Name Column -->
    <ng-container matColumnDef="lastName">
      <mat-header-cell *matHeaderCellDef>Sobrenome</mat-header-cell>
      <mat-cell *matCellDef="let element">{{ element.lastName }}</mat-cell>
    </ng-container>
    <!-- UserName Column -->
    <ng-container matColumnDef="username">
        <mat-header-cell *matHeaderCellDef>Username</mat-header-cell>
        <mat-cell *matCellDef="let element">{{ element.username }}</mat-cell>
      </ng-container>
      <!-- Email Column -->
      <ng-container matColumnDef="email">
        <mat-header-cell *matHeaderCellDef>E-mail</mat-header-cell>
        <mat-cell *matCellDef="let element">{{ element.email }}</mat-cell>
      </ng-container>
      <!-- 假设还有 'actions' 列 -->
      <ng-container matColumnDef="actions">
        <mat-header-cell *matHeaderCellDef> Ações </mat-header-cell>
        <mat-cell *matCellDef="let element">
          <!-- 您的操作按钮 -->
        </mat-cell>
      </ng-container>

    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>

gerenciamento-usuarios-lista.component.ts

import { Component, OnInit, Input } from '@angular/core';
// 假设您的服务路径和模型结构
import { GerenciamentoUsuariosService } from './gerenciamento-usuarios.service';

@Component({
  selector: 'app-gerenciamento-usuarios-lista',
  templateUrl: './gerenciamento-usuarios-lista.component.html',
  styleUrls: ['./gerenciamento-usuarios-lista.component.css']
})
export class GerenciamentoUsuariosListaComponent implements OnInit {
  @Input() usuarios: any[] = []; // 用于在模板中显示和过滤的用户列表
  _allUsuarios: any[] = []; // 存储从服务获取的完整用户列表
  searchTerm: string = ''; // 通用搜索关键词

  readonly displayedColumns = ['firstName', 'lastName', 'username', 'email', 'actions'];

  constructor(private service: GerenciamentoUsuariosService) {}

  ngOnInit(): void {
    this.refreshListUser1();
  }

  refreshListUser1() {
    this.service.list().subscribe(
      resp => {
        this._allUsuarios = resp.content; // 将完整数据存储到 _allUsuarios
        this.usuarios = [...this._allUsuarios]; // 初始化显示列表为完整列表
        console.log(this.usuarios);
      },
      error => {
        console.error('Error fetching user list:', error);
        // 处理错误情况,例如显示错误消息
      }
    );
  }

  Search() {
    // 检查搜索关键词是否为空或只包含空白字符
    if (this.searchTerm.trim() !== "") {
      const keyword = this.searchTerm.toLocaleLowerCase().trim(); // 转换为小写并去除首尾空格

      this.usuarios = this._allUsuarios.filter(res => {
        // 对每个字段进行大小写不敏感的模糊匹配,使用 || 连接多个条件
        return (res.firstName && res.firstName.toLocaleLowerCase().includes(keyword)) ||
               (res.lastName && res.lastName.toLocaleLowerCase().includes(keyword)) ||
               (res.username && res.username.toLocaleLowerCase().includes(keyword)) ||
               (res.email && res.email.toLocaleLowerCase().includes(keyword));
      });
    } else {
      // 如果搜索关键词为空,则将显示列表重置为完整的原始列表
      this.usuarios = [...this._allUsuarios];
    }
  }
}

注意事项:

  • 空值检查: 在进行 toLocaleLowerCase() 或 includes() 操作之前,最好检查字段是否存在(例如 res.firstName && res.firstName.toLocaleLowerCase().includes(keyword)),以防止某些用户对象缺少特定字段时抛出错误。
  • 性能优化: 对于非常庞大的数据集(数千条甚至更多),客户端进行全量过滤可能会影响性能。在这种情况下,考虑将过滤逻辑迁移到后端服务器,让服务器负责数据检索和过滤,只返回匹配的结果。
  • 防抖 (Debounce): (input) 事件会在每次按键时触发 Search() 方法。为了避免过于频繁的过滤操作(尤其是在用户快速输入时),可以考虑引入防抖机制,例如使用 rxjs 的 debounceTime 操作符,在用户停止输入一段时间后才执行搜索。
  • 用户体验: 可以在搜索框旁边添加一个清除按钮,方便用户快速清空搜索内容。

总结

通过以上步骤,我们成功地将一个基本的单字段过滤功能扩展为强大的多字段模糊搜索。核心思想是维护一份完整的原始数据列表,并在每次搜索时从这份原始数据中进行过滤,同时利用 Array.prototype.filter 和逻辑或操作符实现对多个字段的灵活匹配。这种方法不仅提高了代码的复用性和可维护性,也极大地增强了用户在数据列表中的检索能力。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

49

2026.02.13

TypeScript全栈项目架构与接口规范设计
TypeScript全栈项目架构与接口规范设计

本专题面向全栈开发者,系统讲解基于 TypeScript 构建前后端统一技术栈的工程化实践。内容涵盖项目分层设计、接口协议规范、类型共享机制、错误码体系设计、接口自动化生成与文档维护方案。通过完整项目示例,帮助开发者构建结构清晰、类型安全、易维护的现代全栈应用架构。

196

2026.02.25

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

37

2026.03.13

点击input框没有光标怎么办
点击input框没有光标怎么办

点击input框没有光标的解决办法:1、确认输入框焦点;2、清除浏览器缓存;3、更新浏览器;4、使用JavaScript;5、检查硬件设备;6、检查输入框属性;7、调试JavaScript代码;8、检查页面其他元素;9、考虑浏览器兼容性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

197

2023.11.24

PHP 高并发与性能优化
PHP 高并发与性能优化

本专题聚焦 PHP 在高并发场景下的性能优化与系统调优,内容涵盖 Nginx 与 PHP-FPM 优化、Opcode 缓存、Redis/Memcached 应用、异步任务队列、数据库优化、代码性能分析与瓶颈排查。通过实战案例(如高并发接口优化、缓存系统设计、秒杀活动实现),帮助学习者掌握 构建高性能PHP后端系统的核心能力。

114

2025.10.16

PHP 数据库操作与性能优化
PHP 数据库操作与性能优化

本专题聚焦于PHP在数据库开发中的核心应用,详细讲解PDO与MySQLi的使用方法、预处理语句、事务控制与安全防注入策略。同时深入分析SQL查询优化、索引设计、慢查询排查等性能提升手段。通过实战案例帮助开发者构建高效、安全、可扩展的PHP数据库应用系统。

99

2025.11.13

JavaScript 性能优化与前端调优
JavaScript 性能优化与前端调优

本专题系统讲解 JavaScript 性能优化的核心技术,涵盖页面加载优化、异步编程、内存管理、事件代理、代码分割、懒加载、浏览器缓存机制等。通过多个实际项目示例,帮助开发者掌握 如何通过前端调优提升网站性能,减少加载时间,提高用户体验与页面响应速度。

36

2025.12.30

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

103

2026.03.06

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.9万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

CSS教程
CSS教程

共754课时 | 43万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号