Angular嵌套对象数组递归函数问题:自定义过滤管道遇无限循环
解决嵌套对象数组过滤的递归函数无限循环问题
我帮你梳理下当前代码里的核心问题,然后给出可行的完整解决方案:
当前代码的问题分析
- 匹配逻辑完全错误:你写的
if(obj === searchTerm)是拿整个对象和搜索词做对比,这永远不会命中(除非搜索词本身是该对象的引用),导致递归无意义地遍历所有嵌套结构,甚至遇到null时(typeof null === 'object')还会继续递归,最终引发无限循环或栈溢出。 - forEach的return无效:
forEach遍历中使用return不会终止循环,而且你的函数没有返回值,没法判断当前分支是否找到匹配项,也就无法完成过滤逻辑。 - 未处理数组类型:你的数据源是数组结构,但当前代码只处理了对象,没考虑遍历数组元素的情况。
- 未排除无效值:当属性值是
null或undefined时,typeof也会返回object,导致递归进入无效值,引发异常。
修正后的完整实现
下面是包含递归匹配逻辑的Angular过滤管道完整代码,能正确处理嵌套对象和数组的全局搜索:
第一步:实现递归匹配函数
这个函数会递归遍历所有层级的对象/数组,检查是否有任意属性值匹配搜索词(支持大小写不敏感匹配):
private matchesSearchTerm(item: any, searchTerm: string): boolean { const lowerCaseSearch = searchTerm.toLowerCase(); // 处理数组:只要有一个元素匹配就返回true if (Array.isArray(item)) { return item.some(element => this.matchesSearchTerm(element, lowerCaseSearch)); } // 处理有效对象:遍历所有属性递归检查 if (typeof item === 'object' && item !== null) { return Object.keys(item).some(key => { return this.matchesSearchTerm(item[key], lowerCaseSearch); }); } // 处理基础类型:转为字符串后做包含匹配 const itemStr = String(item).toLowerCase(); return itemStr.includes(lowerCaseSearch); }
第二步:完整的Angular管道代码
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'filtro' }) export class FiltroPipe implements PipeTransform { transform(workOrders: any[], searchTerm: string): any[] { // 边界处理:数组为空或搜索词为空时直接返回原数组 if (!workOrders || !searchTerm) { return workOrders || []; } // 过滤数组,保留匹配搜索词的订单 return workOrders.filter(order => this.matchesSearchTerm(order, searchTerm)); } private matchesSearchTerm(item: any, searchTerm: string): boolean { const lowerCaseSearch = searchTerm.toLowerCase(); if (Array.isArray(item)) { return item.some(element => this.matchesSearchTerm(element, lowerCaseSearch)); } if (typeof item === 'object' && item !== null) { return Object.keys(item).some(key => { return this.matchesSearchTerm(item[key], lowerCaseSearch); }); } const itemStr = String(item).toLowerCase(); return itemStr.includes(lowerCaseSearch); } }
关键改进说明
- 清晰的递归终止条件:明确区分数组、有效对象、基础类型,避免无意义的递归。
- 避免无限循环:排除了
null和非对象类型的递归路径,确保递归只在有效的嵌套结构中进行。 - 友好的匹配逻辑:支持大小写不敏感搜索,把所有值转为字符串后做包含匹配,兼容数字、日期等多种类型。
- 严谨的边界处理:处理了数组为空、搜索词为空的场景,避免运行时报错。
你的视图代码可以保持不变,这个管道会自动递归遍历每个order的所有嵌套属性(比如client.name、job_status.name、tech.eta_promise_date等),只要任意层级的属性值包含搜索词,就会保留该订单。
内容的提问来源于stack exchange,提问作者Carlos Aponte
相关产品推荐
相关产品推荐

