Angular嵌套数组搜索Pipe实现:需同时过滤gname与ename
解决方案
1. 修复TypeScript类型错误:定义数据接口
先给你的数据结构明确TypeScript类型,彻底解决隐式any的类型错误:
// 定义desc数组元素的类型 export interface DescItem { id: number; ename: string; } // 定义主数组元素的类型 export interface AccItem { gname: string; desc: DescItem[]; gid: number; }
然后在组件中给abb指定类型:
this.abb: AccItem[] = [ {gname:'gname3', desc:[{id:123, ename:'Australia'}, {id:456, ename:'Austria'}], gid:7777}, {gname:'gname1', desc:[{id:899, ename:'France'}], gid:8876}, {gname:'gname2', desc:[{id:676, ename:'Germany'}], gid:993} // 注意:0993是无效数字,已修正为993 ];
2. 重写SearchPipe实现多字段嵌套过滤
修改Pipe逻辑,实现同时匹配gname或desc数组中的ename,并保留匹配的内容:
import { Pipe, PipeTransform } from '@angular/core'; import { AccItem, DescItem } from './your-component-path'; // 替换为接口实际存放路径 @Pipe({ name: 'search' }) export class SearchPipe implements PipeTransform { transform(value: AccItem[], searchTerm: string): AccItem[] { // 搜索词为空时直接返回原数组 if (!searchTerm.trim()) { return value; } const lowerSearch = searchTerm.toLowerCase(); return value.reduce((resultList, currentItem) => { // 检查gname是否匹配(不区分大小写) const gnameMatch = currentItem.gname.toLowerCase().includes(lowerSearch); // 过滤desc中匹配ename的项 const matchedDescItems = currentItem.desc.filter(item => item.ename.toLowerCase().includes(lowerSearch) ); // 只要gname匹配,或者有匹配的desc项,就处理后加入结果 if (gnameMatch || matchedDescItems.length > 0) { const processedItem = { ...currentItem, // gname匹配则保留所有desc,否则只保留匹配的desc项 desc: gnameMatch ? currentItem.desc : matchedDescItems }; resultList.push(processedItem); } return resultList; }, [] as AccItem[]); } }
3. HTML模板使用
原模板无需修改,直接使用更新后的Pipe即可:
<div> <div class="card-header" *ngFor="let acc of abb | search: searchTerm; let i = index"> {{acc.gname}} <ng-container *ngFor="let ret of acc.desc; let j = index"> <div class="card-body"> {{ret.id}} - {{ret.ename}} </div> </ng-container> </div> </div>
关键细节说明
- 模糊匹配:使用
toLowerCase()和includes()实现不区分大小写的模糊搜索,如需严格匹配,将includes替换为===即可。 - 结果逻辑:如果
gname匹配,会保留该条目的所有desc项;如果只有desc中的ename匹配,则只显示匹配的desc项,同时保留对应的gname。 - 类型安全:通过定义接口,彻底消除TypeScript的类型警告。
内容的提问来源于stack exchange,提问作者Vinodh Ganesh
相关产品推荐
相关产品推荐

