如何调整搜索过滤代码,实现大小写兼容的用户数据查询?
问题解决:实现大小写不敏感的用户搜索
你的代码核心问题出在手动过滤dataSourceUserFiltered时没有统一做大小写转换:虽然filterPredicate部分已经处理了大小写匹配逻辑,但后续手动筛选的逻辑没同步,导致输入大写时(实际filterValue已被转成小写),原数据的大写字段无法匹配小写的filterValue。
原代码问题点
applyUserFilter(event: Event) { const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase(); this.dataSourceUserNonFiltered.filterPredicate = (data: User, filter: string) => { const email = data.email.toLowerCase().includes(filter); const status = data.status.toLowerCase().includes(filter); const role = data.role.toLowerCase().includes(filter); return email || status || role; }; this.dataSourceUserNonFiltered.filter = filterValue; if (filterValue) { // 此处未转换user.email大小写,导致原大写字段无法匹配小写filterValue this.dataSourceUserFiltered.data = this.dataSourceUserNonFiltered.data.filter(user => user.email.includes(filterValue)) } else { this.setUserDefaultListValue(); } this._cdr.detectChanges(); }
修改方案
以下两种方式任选其一即可实现需求:
方式1:同步手动过滤的大小写转换
给手动过滤的字段也添加大小写转换,统一匹配逻辑:
applyUserFilter(event: Event) { const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase(); this.dataSourceUserNonFiltered.filterPredicate = (data: User, filter: string) => { const email = data.email.toLowerCase().includes(filter); const status = data.status.toLowerCase().includes(filter); const role = data.role.toLowerCase().includes(filter); return email || status || role; }; this.dataSourceUserNonFiltered.filter = filterValue; if (filterValue) { // 新增toLowerCase(),统一大小写判断规则 this.dataSourceUserFiltered.data = this.dataSourceUserNonFiltered.data.filter(user => user.email.toLowerCase().includes(filterValue) ) } else { this.setUserDefaultListValue(); } this._cdr.detectChanges(); }
方式2:复用已过滤的数据源(更高效)
既然已经通过dataSourceUserNonFiltered的filterPredicate完成了过滤,直接复用其结果即可,避免重复遍历数据:
applyUserFilter(event: Event) { const filterValue = (event.target as HTMLInputElement).value.trim().toLowerCase(); this.dataSourceUserNonFiltered.filterPredicate = (data: User, filter: string) => { const email = data.email.toLowerCase().includes(filter); const status = data.status.toLowerCase().includes(filter); const role = data.role.toLowerCase().includes(filter); return email || status || role; }; this.dataSourceUserNonFiltered.filter = filterValue; if (filterValue) { // 直接取数据源已过滤后的结果,无需手动二次筛选 this.dataSourceUserFiltered.data = this.dataSourceUserNonFiltered.filteredData; } else { this.setUserDefaultListValue(); } this._cdr.detectChanges(); }
补充说明
两种方式都能实现输入任意大小写都能匹配对应数据的效果,方式2更符合Angular Material数据源的设计逻辑,减少不必要的性能消耗。如果之前调整后出现只能搜大写的情况,大概率是误将filterValue转成了大写,或未对数据字段做大小写转换,现在统一将搜索值和数据字段转成同一种大小写(小写/大写均可),就能稳定实现大小写不敏感匹配。
内容的提问来源于stack exchange,提问作者Clark Lester Camiring
相关产品推荐
相关产品推荐

