Angular使用Autocomplete聚焦输入框触发filter报未定义错误
问题原因
报错核心是触发focus事件执行filter方法时,组件内的chatList变量值为undefined,调用undefined.filter()会直接抛出类型错误。
出现该问题的具体逻辑:
- 输入框绑定了
(focus)="filter('')"事件,点击输入框获得焦点的瞬间就会执行过滤逻辑 - 一般场景下
chatList是接口异步拉取的数据,首次聚焦触发事件时,接口数据还未返回,chatList还没完成赋值 - 后续输入内容触发
ngModelChange时,异步请求已经完成、chatList已经被赋值为数组,所以筛选功能可以正常运行
另外模板中存在一个隐藏的绑定错误:[ngModel]="chatList"写法有误,ngModel需要绑定输入框对应的输入/选中值变量,而不是整个待筛选的聊天列表数组,该问题会导致输入框初始显示异常、选中选项后值回显错误。
修复方案
按以下步骤调整即可解决问题:
- 给涉及的列表属性设置初始空数组,从根源避免未定义问题
在组件类声明属性时直接赋默认值:
// 待筛选的全量聊天列表,初始为空数组 chatList: any[] = []; // 过滤后的下拉列表,初始为空数组,避免模板初次渲染报错 filteredObject: any[] = []; // 输入框绑定的选中值变量 selectedUser: any;
- 优化filter方法,增加数组合法性判断,兼容数据未加载完成的场景
filter(value = '') { // 待筛选列表不存在、入参不是字符串时直接返回空列表 if (!Array.isArray(this.chatList) || typeof value !== 'string') { this.filteredObject = []; return; } const searchKey = value.toLocaleLowerCase(); this.filteredObject = this.chatList.filter( item => item.Name?.toLocaleLowerCase().includes(searchKey) ); }
- 修正模板中ngModel的错误绑定
<input type="text" matInput [ngModel]="selectedUser" [matAutocomplete]="autocopmlete" (focus)="filter('')" (ngModelChange)="filter($event)"> <mat-autocomplete #autocopmlete="matAutocomplete" [displayWith]="displayName"> <mat-option *ngFor="let item of filteredObject" [value]="item" (onSelectionChange)="selectUser(item)"> {{ item.Name }} </mat-option> </mat-autocomplete>
- (可选优化)如果
chatList是接口异步获取的,在拿到接口返回值给chatList赋值后,主动调用一次filter(''),可以保证下拉列表初始就加载全量数据,不用等聚焦事件触发才渲染选项。
内容的提问来源于stack exchange,提问作者user3653474
相关产品推荐
相关产品推荐

