Angular 5 Material Table:替换filterPredicate为不同参数类型的函数
实现Material 2表格的多条件自定义过滤函数
嘿,我刚好做过Material 2表格的自定义多条件过滤需求,给你把这个customFilterPredicate函数补全并优化一下,完美支持多过滤器组合:
首先我们先明确过滤器的结构,我定义了一个Predicate接口来规范每个过滤条件的格式,这样代码更清晰:
// 先定义过滤器的结构 interface Predicate { field: keyof Coin; // 要过滤的字段名,关联你的Coin类型 operator: '>=' | '<=' | '>' | '<' | '=='; // 支持的操作符 value: string; // 过滤值(统一用字符串接收,后续转成对应类型) } customFilterPredicate(data: Coin, filters: Predicate[]): boolean { // 定义操作符对应的比较逻辑 const operators = { '>=': (a: number, b: number) => a >= b, '<=': (a: number, b: number) => a <= b, '>': (a: number, b: number) => a > b, '<': (a: number, b: number) => a < b, '==': (a: any, b: any) => a === b // 支持字符串等其他类型的精确匹配 }; // 没有过滤器时,直接返回true(显示所有数据) if (filters.length === 0) return true; // 这里默认用AND逻辑:所有过滤条件必须同时满足 let result = true; for (const filter of filters) { const fieldValue = data[filter.field]; // 把字段值和过滤值转成数字(针对price这类数值型字段) const numFieldValue = typeof fieldValue === 'number' ? fieldValue : Number(fieldValue); const numFilterValue = Number(filter.value); // 容错处理:如果遇到不支持的操作符,跳过并提示 if (!operators[filter.operator]) { console.warn(`暂不支持该操作符:${filter.operator}`); continue; } // 应用当前过滤条件,只要有一个不满足,结果就变为false result = result && operators[filter.operator](numFieldValue, numFilterValue); // 提前跳出循环优化性能:已经不满足条件了,没必要继续遍历 if (!result) break; } // 如果需要OR逻辑(只要满足一个条件即可),可以把上面的代码改成下面这样: // let result = false; // for (const filter of filters) { // // 同样的字段转换和操作符检查逻辑 // const fieldValue = data[filter.field]; // const numFieldValue = typeof fieldValue === 'number' ? fieldValue : Number(fieldValue); // const numFilterValue = Number(filter.value); // // if (!operators[filter.operator]) { // console.warn(`暂不支持该操作符:${filter.operator}`); // continue; // } // // result = result || operators[filter.operator](numFieldValue, numFilterValue); // // 提前跳出:已经满足条件了,没必要继续遍历 // if (result) break; // } return result; }
怎么用这个函数?
在组件里把它绑定到表格数据源的filterPredicate上就行,然后通过更新过滤器数组来触发过滤:
// 初始化表格数据源时绑定自定义过滤函数 this.dataSource.filterPredicate = this.customFilterPredicate.bind(this); // 举个例子:添加一个"price > 1"的过滤条件 this.filters.push({ field: 'price', operator: '>', value: '1' }); // 再添加一个"price <= 10"的条件,实现多条件组合 this.filters.push({ field: 'price', operator: '<=', value: '10' }); // 触发表格重新过滤(Material表格要求filter必须是字符串,所以把过滤器数组转成JSON) this.dataSource.filter = JSON.stringify(this.filters);
一些额外提示
- 如果需要支持字符串模糊过滤,可以给
operators加个contains逻辑:'contains': (a: string, b: string) => a.toLowerCase().includes(b.toLowerCase()) - 转换数字时可以加NaN判断,避免无效输入导致的错误:
if (isNaN(numFieldValue) || isNaN(numFilterValue)) { console.warn(`过滤值或字段值不是有效数字`); continue; } - 如果要支持更复杂的过滤组合(比如AND嵌套OR),可以扩展
Predicate结构,加入分组标识,但基础的AND/OR逻辑已经能覆盖大部分场景了。
内容的提问来源于stack exchange,提问作者Paul Etscheit
相关产品推荐
相关产品推荐

