在Angular项目中实现高效多字段模糊搜索与数据过滤


在Angular项目中实现高效多字段模糊搜索与数据过滤

本教程详细指导如何在angular应用中为数据列表实现多字段模糊搜索功能。我们将从现有单字段过滤逻辑出发,逐步优化为支持姓名、邮箱、用户名等多个字段的灵活查询。教程将深入探讨如何利用j*ascript的数组和字符串方法进行高效过滤,并介绍如何有效管理原始数据与过滤结果,确保搜索体验流畅且高效。

1. 理解数据过滤与模糊匹配的核心概念

在Web应用中,数据列表的过滤是一个常见需求。用户通常希望通过输入关键词来快速查找相关信息。实现这一功能的核心在于以下几个J*aScript数组和字符串方法:

  • Array.prototype.filter(): 这是J*aScript数组的一个高阶函数,它创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。它是实现数据过滤的基础。
  • String.prototype.toLocaleLowerCase(): 此方法将字符串转换为小写,通常用于实现大小写不敏感的比较,确保搜索结果的全面性。
  • String.prototype.includes(): 此方法用于判断一个字符串是否包含在另一个字符串中,返回 true 或 false。它是实现模糊匹配(即部分匹配)的关键。
  • 逻辑或运算符 (||): 当需要在一个搜索关键词匹配多个字段中的任意一个时,可以使用 || 运算符连接多个条件。

2. 现有实现与优化点分析

原始代码展示了一个基于mat-table的用户列表,并实现了一个简单的单字段(lastName)过滤功能。

原始HTML片段:

<input type="text" [(ngModel)]="lastname" (input)="Search()"/>
<mat-table [dataSource]="usuarios">
    <!-- ... 省略其他列定义 ... -->
    <ng-container matColumnDef="firstName">
      <mat-header-cell *matHeaderCellDef> Nome </mat-header-cell>
      <mat-cell *matCellDef="let element">{{ element.firstName }}</mat-cell>
    </ng-container>
    <ng-container matColumnDef="lastName">
      <mat-header-cell *matHeaderCellDef>Sobrenome</mat-header-cell>
      <mat-cell *matCellDef="let element">{{ element.lastName }}</mat-cell>
    </ng-container>
    <ng-container matColumnDef="username">
        <mat-header-cell *matHeaderCellDef>Username</mat-header-cell>
        <mat-cell *matCellDef="let element">{{ element.username }}</mat-cell>
      </ng-container>
      <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>

原始TypeScript片段:

export class GerenciamentoUsuariosListaComponent implements OnInit {
  @Input() usuarios: any[] = []; // 显示的数据源
  usuarios1: any; // 似乎用于临时存储,但未充分利用
  lastname :string; // 搜索关键词,仅用于姓氏

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

  constructor(private service: GerenciamentoUsuariosService) {
    this.lastname = '';
  }

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

  refreshListUser1() {
    this.usuarios1 = this.service.list().subscribe(
      resp => {
        this.usuarios = resp.content // 直接赋值给显示数据源
       console.log(this.usuarios)
      });
  }

  Search(){
    if(this.lastname != ""){
      this.usuarios = this.usuarios.filter(res =>{
        return res.lastName.toLocaleLowerCase().match(this.lastname.toLocaleLowerCase());
      })
    }else if(this.lastname == ""){
      this.ngOnInit(); // 问题:清空搜索词时会重新加载数据
    }
  }
}

现有实现存在以下优化点:

  1. 单字段限制: Search() 方法目前只针对 lastName 字段进行过滤,无法满足多字段(firstName, username, email)的搜索需求。
  2. 数据源管理: 当搜索词为空时,Search() 方法会调用 ngOnInit() 重新获取数据。这会导致不必要的网络请求,并且在用户频繁清空搜索词时影响性能和用户体验。更优的做法是维护一份原始的完整数据列表,在需要重置过滤时直接使用这份数据。
  3. 变量命名: lastname 变量名不够通用,当实现多字段搜索时,应使用更具描述性的名称,如 searchTerm。
  4. 过滤逻辑: match() 方法通常用于正则表达式匹配,对于简单的字符串包含判断,includes() 方法更为直观和高效。

3. 实现多字段过滤的步骤

我们将对上述代码进行改进,以实现高效的多字段模糊搜索。

3.1 步骤一:更新HTML模板

首先,我们将搜索输入框的 [(ngModel)] 绑定到一个更通用的变量 searchTerm。

<input type="text" [(ngModel)]="searchTerm" (input)="Search()" placeholder="搜索姓名、邮箱或用户名"/>

<mat-table [dataSource]="usuarios">
    <!-- Name Column -->
    <ng-container matColumnDef="firstName">
      <mat-header-cell *matHeaderCellDef> 姓名 </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>姓氏</mat-header-cell>
      <mat-cell *matCellDef="let element">{{ element.lastName }}</mat-cell>
    </ng-container>
    <!-- UserName Column -->
    <ng-container matColumnDef="username">
        <mat-header-cell *matHeaderCellDef>用户名</mat-header-cell>
        <mat-cell *matCellDef="let element">{{ element.username }}</mat-cell>
      </ng-container>
      <!-- Email Column -->
      <ng-container matColumnDef="email">
        <mat-header-cell *matHeaderCellDef>电子邮件</mat-header-cell>
        <mat-cell *matCellDef="let element">{{ element.email }}</mat-cell>
      </ng-container>
      <!-- ... 其他列和操作按钮 ... -->
</mat-table>

3.2 步骤二:调整组件逻辑 (TypeScript)

在组件中,我们将引入一个新数组 originalUsuarios 来存储从后端获取的完整用户列表。usuarios 数组将始终用于显示过滤后的结果。

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.scss']
})
export class GerenciamentoUsuariosListaComponent implements OnInit {
  @Input() usuarios: any[] = []; // 用于显示和过滤的数据列表
  originalUsuarios: any[] = []; // 存储原始的完整数据列表
  searchTerm: string = ''; // 通用的搜索关键词

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

  constructor(private service: GerenciamentoUsuariosService) { }

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

  refreshListUser1(): void {
    this.service.list().subscribe(
      resp => {
        this.originalUsuarios = resp.content; // 将完整数据存储到 originalUsuarios
        this.usuarios = [...this.originalUsuarios]; // 初始化显示列表为完整数据
        console.log(this.usuarios);
      },
      error => {
        console.error('获取用户列表失败:', error);
        // 处理错误,例如显示错误消息给用户
      }
    );
  }

  Search(): void {
    const keyword = this.searchTerm.toLocaleLowerCase().trim(); // 获取并转换为小写,去除首尾空格

    if (keyword) {
      // 如果有搜索关键词,则从原始数据中过滤
      this.usuarios = this.originalUsuarios.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.originalUsuarios];
    }
  }
}

代码解释:

1.1.8PbootCMS 1.1.8PbootCMS

PbootCMS是一款高效、简洁、强悍的开源PHP企业网站开发建设管理系统。 PbootCMS 1.1.8 更新日志:2018-08-07 1.修复提交表单多选字段接收数据问题; 2.修复登录过程中二次登陆在页面不刷新时验证失败问题; 3.新增搜索结果fuzzy参数来控制是否模糊匹配; 4.新增父分类,顶级分类名称及链接独立标签,具体见手册; 5.新增内容多图拖动排序功能。

1.1.8PbootCMS 243 查看详情 1.1.8PbootCMS
  1. originalUsuarios: any[] = [];: 新增一个数组用于存储从后端获取的未过滤的完整用户列表。
  2. searchTerm: string = '';: 将 lastname 变量重命名为 searchTerm,使其更通用。
  3. refreshListUser1() 方法修改:
    • 在订阅数据后,首先将 resp.content 赋值给 this.originalUsuarios,确保我们始终有一份完整的数据副本。
    • 然后,使用 this.usuarios = [...this.originalUsuarios]; 将显示列表初始化为完整数据。使用扩展运算符 ... 创建一个副本,以避免直接引用导致意外修改 originalUsuarios。
  4. Search() 方法修改:
    • const keyword = this.searchTerm.toLocaleLowerCase().trim();: 获取搜索词,转换为小写,并使用 trim() 移除可能存在的空白字符,提高搜索准确性。
    • if (keyword): 判断搜索词是否非空。
      • 如果非空: this.usuarios = this.originalUsuarios.filter(...)。这里是关键:我们总是从 originalUsuarios (完整数据)开始过滤,而不是从当前 usuarios (可能已经过滤过的数据)过滤。这确保了每次搜索都是基于完整数据集。过滤条件使用 || 连接多个字段的 includes() 方法,实现了多字段的模糊匹配。
      • 如果为空: this.usuarios = [...this.originalUsuarios];。将显示列表重置为原始的完整用户列表,避免了重新请求数据。

4. 注意事项与进阶考量

  • 性能优化 (去抖/Debounce): 对于包含大量数据或用户输入非常频繁的场景,input 事件可能触发 Search() 方法过于频繁。可以考虑使用 RxJS 的 debounceTime 操作符来延迟 Search() 方法的执行,例如:

    import { Subject } from 'rxjs';
    import { debounceTime } from 'rxjs/operators';
    
    export class GerenciamentoUsuariosListaComponent implements OnInit, OnDestroy {
      // ... 其他变量 ...
      private searchTerms = new Subject<string>();
      private destroy$ = new Subject<void>(); // 用于管理订阅的生命周期
    
      constructor(private service: GerenciamentoUsuariosService) { }
    
      ngOnInit(): void {
        this.refreshListUser1();
    
        this.searchTerms.pipe(
          debounceTime(300), // 300毫秒内没有新输入则执行
          takeUntil(this.destroy$) // 组件销毁时取消订阅
        ).subscribe(() => {
          this.Search();
        });
      }
    
      // 在HTML中调用这个方法
      onSearchInput(): void {
        this.searchTerms.next(this.searchTerm);
      }
    
      ngOnDestroy(): void {
        this.destroy$.next();
        this.destroy$.complete();
      }
    
      // ... Search() 方法保持不变 ...
    }

    HTML中将 (input)="Search()" 改为 (input)="onSearchInput()"。

  • 可扩展性: 如果需要过滤的字段非常多,或者过滤条件需要动态配置,可以考虑将过滤逻辑抽象成一个独立的函数或服务,甚至使用第三方库(如 lodash 的 filter 或自定义管道 Pipe)。

  • 后端过滤: 对于非常大的数据集(例如数万条甚至更多),前端进行过滤可能会导致性能瓶颈。在这种情况下,更推荐将过滤逻辑推送到后端API实现,前端只负责发送搜索关键词并接收过滤后的数据。

  • 用户体验: 考虑在数据加载或过滤时显示加载指示器(如 mat-spinner),并在没有搜索结果时显示友好的提示信息。

  • 完全匹配 vs. 模糊匹配: 当前实现是模糊匹配 (includes())。如果需要完全匹配,可以将 includes(keyword) 替换为 === keyword。

5. 总结

通过本教程,我们学习了如何在Angular项目中实现一个健壮且高效的多字段模糊搜索功能。关键在于:

  1. 维护原始数据副本: 确保在组件中始终有一份完整的、未过滤的数据源,以便进行重置和新的过滤操作。
  2. 利用J*aScript数组和字符串方法: 熟练运用 filter(), toLocaleLowerCase(), includes() 以及逻辑或运算符 || 来构建灵活的过滤条件。
  3. 优化搜索逻辑: 避免不必要的网络请求,并考虑性能优化(如去抖)来提升用户体验。

掌握这些技巧,您将能够为您的Angular应用构建出更加强大和用户友好的数据列表过滤功能。

以上就是在Angular项目中实现高效多字段模糊搜索与数据过滤的详细内容,更多请关注其它相关文章!


# 运算符  # 湖北网站建设申请费用  # 瓦房店外贸网站建设推广  # 台州抖音seo  # 网站优化与推广定制  # 网站建设频道是什么  # 昌邑pc网站建设  # 免费网站建设排行  # 绍兴网站优化企业  # 丰台区个人网站优化单价  # 百度seo模拟点击  # 转换为  # 后端  # 搜索结果  # 用户列表  # css  # 多个  # 关键词  # 网站开发建设管理系统  # 多字  # app  # typescript  # 正则表达式  # go  # 前端  # js  # html  # java  # word  # javascript 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: 解决Go encoding/json 将JSON大数字解析为浮点数的问题  钉钉任务无法提醒如何处理 钉钉任务提醒优化方法  芒果TV官网登录入口 芒果TV官方网站登录入口  鼠标没反应了怎么办 无线/有线鼠标失灵的解决方法【详解】  猫眼app抢票快还是小程序快  Golang如何使用gRPC拦截器实现日志收集_Golang gRPC拦截器日志收集实践  解决VS Code中Python版本冲突与输出异常的指南  哔哩哔哩黑名单怎么查看  Pandas中基于动态偏移量实现DataFrame列值位移的策略  感染了幽门螺杆菌一定会导致胃癌吗?蚂蚁庄园今日答案最新11.30  KFC邀请码怎么使用领额外优惠_KFC邀请码输入方式与额外优惠代码获取方法  Win10通知横幅停留时间修改 Win10自定义通知显示时长【技巧】  Composer reinstall命令重装损坏的包  在J*a里什么是行为抽象_抽象行为对代码复用的提升作用  C++ bind函数使用教程_C++参数绑定与函数适配器的应用  《磁力猫》最好用的磁官网  网页版网易云音乐入口_网易云音乐在线官网登录  J*aScript事件处理:优化键盘输入与表单提交的实践指南  Go语言反射机制下访问嵌入结构体中的被遮蔽方法  Golang如何使用crypto/md5生成哈希_Golang MD5哈希生成方法  CSS过渡如何实现按钮悬停效果_transition属性控制背景颜色变化  mail.qq.com登录入口 QQ邮箱网页版直达  Keras中Convolution2D层及其核心辅助层详解  Highcharts雷达图径向轴数值标签实现教程  晨报|开发商暗示《空洞骑士:丝之歌》DLC开发中 《合金装备4》有望重制  sf漫画官网登录入口直达_sf漫画官方正版网址  Python csv 模块处理非字符串数据:列表写入 CSV 文件的机制解析  海棠阅读网页版_进入海棠网页版在线阅读中心  B站怎么开|直播| B站|直播|申请需要什么条件【新手必看】  京东快递包裹信息查询入口 京东快递官方查询平台入口  菜鸟驿站的取件码忘了怎么办 手机快速查询指南  猫眼电影app怎么查询电影院的营业时间_猫眼电影影院营业时间查询教程  如何查询国外邮政编码_国外邮政编码查询的多种有效途径  C++二维数组动态分配方法_C++指针与数组内存布局  Python模块化编程:避免循环导入与共享函数的最佳实践  《宝可梦大集结》S4冠军之路开始时间介绍  4399正版网页版入口高清直达链接  优酷下载视频的清晰度怎么选_优酷缓存清晰度设置与选择指南  Win11便笺在哪打开 Win11桌面便笺(Sticky Notes)使用方法【详解】  荣耀Magic7拍照夜景噪点处理_荣耀Magic7相机优化  花生壳内网映射新方案  西瓜视频怎么查看访客记录_西瓜视频访客记录查看方法  RxJS中如何高效地在一个函数内处理和合并多个数据集合  Lar*el如何创建自定义的辅助函数(Helpers)_Lar*el全局函数定义与加载方法  使用TinyButStrong生成HTML并结合Dompdf创建PDF教程  手机远程连接电脑方法  抖音评论无法发送如何修复 抖音评论功能操作指南  J*a中导出MySQL表为SQL脚本的两种方法  PHP odbc_fetch_array 返回值处理:如何正确访问嵌套数组元素  海棠阅读登录教程_详细讲解海棠登录操作 

 2025-11-20

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.