Angular Material表格中嵌套对象的搜索——自定义过滤谓词
实现Angular Material表格嵌套数据的搜索功能
两种实现方案,根据你的需求选择:
方案1:通用递归搜索(自动匹配所有嵌套字段)
适合不确定嵌套结构,需要搜索所有层级数据的场景。先写一个递归函数遍历对象的所有值,再修改搜索逻辑:
// 递归检查对象是否包含搜索词 private doesItemMatch(item: any, searchTerm: string): boolean { const lowerTerm = searchTerm.toLowerCase(); for (const value of Object.values(item)) { if (typeof value === 'object' && value !== null) { // 嵌套对象递归查找 if (this.doesItemMatch(value, lowerTerm)) return true; } else { // 基础类型直接匹配 if (value?.toString().toLowerCase().includes(lowerTerm)) return true; } } return false; } // 搜索过滤函数 filterData(searchTerm: string): void { if (!searchTerm.trim()) { this.filteredData = [...this.originalData]; return; } this.filteredData = this.originalData.filter(item => this.doesItemMatch(item, searchTerm) ); }
方案2:指定嵌套字段路径(精准可控)
如果只需要搜索特定的嵌套字段(比如表格中展示的user.address.city、user.contact.email),可以预先定义字段路径,针对性匹配:
// 定义需要搜索的字段(包含平级和嵌套路径) private searchableFields: string[] = [ 'name', 'user.address.city', 'user.contact.email' ]; // 根据路径获取嵌套值 private getNestedValue(item: any, path: string): any { return path.split('.').reduce((current, key) => { return current ? current[key] : null; }, item); } // 搜索过滤函数 filterData(searchTerm: string): void { if (!searchTerm.trim()) { this.filteredData = [...this.originalData]; return; } const lowerTerm = searchTerm.toLowerCase(); this.filteredData = this.originalData.filter(item => { return this.searchableFields.some(field => { const value = this.getNestedValue(item, field); return value?.toString().toLowerCase().includes(lowerTerm); }); }); }
模板使用示例
搜索输入和表格部分保持原有逻辑即可:
<!-- 搜索输入框 --> <mat-form-field appearance="fill"> <mat-label>搜索</mat-label> <input matInput (input)="filterData($event.target.value)"> </mat-form-field> <!-- Angular Material表格 --> <table mat-table [dataSource]="filteredData"> <!-- 嵌套字段列示例 --> <ng-container matColumnDef="city"> <th mat-header-cell *matHeaderCellDef>城市</th> <td mat-cell *matCellDef="let element">{{element.user.address.city}}</td> </ng-container> <!-- 其他列定义... --> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> </table>
注意事项
- 处理空值:嵌套字段可能为
null或undefined,要在取值时做判断避免报错 - 数组嵌套:如果需要搜索数组类型的嵌套数据(比如
user.hobbies),可以在递归函数里增加数组遍历逻辑 - 性能优化:数据量较大时,建议使用指定字段路径的方案,减少不必要的遍历
内容的提问来源于stack exchange,提问作者Avishkar
相关产品推荐
相关产品推荐

