Angular中Mat AutoComplete报valueChanges空值错误,求解决方法
Angular Mat AutoComplete 触发valueChanges空指针错误的修复方案
问题描述
我在Angular项目中使用Mat AutoComplete组件,已成功通过服务获取数据列表,但输入内容时触发错误:ERROR TypeError: Cannot read properties of null (reading 'valueChanges')。以下是我的组件与服务层代码:
组件代码(原错误版本)
filteredOptions: any; options = []; this.serviceLogForm = this.fb.group({ id: [0], Name: [], ArrayForm: this.fb.array([this.CreateArray()]) }) CreateArray(){ return this.fb.group({ item: [''] }) } ngOninit{ this.ArrayForm.get('item').valueChanges.subscribe(response => { console.log('data is ', response); this.filterData(response); }) } filterData(enterData){ this.filteredOptions = this.options.filter(item => { return item.toLowerCase().indexOf(enterData.toLowerCase()) > -1 }) } getData(){ this.services.dataList(true).subscribe((response) => { this.options = response; this.filteredOptions = response; console.log(response) }) }
服务层代码
dataList(isActive: Boolean){ let params = new HttpParams(); params = params.append('isActive', String(isActive)); return this.http.get(this.appsetting.baseURL + 'myList/list',{params}) .pipe( map((response:any) => response.items.map(items =>items['Name'])) ); }
错误原因
ArrayForm是FormArray类型,直接用this.ArrayForm.get('item')会返回null——FormArray的子控件通过索引访问,而非键名。- 生命周期钩子拼写错误:
ngOninit应为ngOnInit()(大写O、I,且带函数括号),导致初始化逻辑未执行。 - 未在组件销毁时清理订阅,存在内存泄漏风险。
修复步骤
- 修正生命周期钩子:将
ngOninit改为标准的ngOnInit(),确保初始化逻辑触发。 - 正确获取FormArray子控件:先获取FormArray实例,通过
at(0)拿到第一个FormGroup,再获取item控件。 - 添加订阅清理:用
Subscription存储订阅对象,在ngOnDestroy中取消订阅。 - 提前加载数据:在
ngOnInit中调用getData(),保证AutoComplete渲染前数据已加载完成。
修正后的组件代码
import { Component, OnInit, OnDestroy } from '@angular/core'; import { FormBuilder, FormGroup, FormArray, Subscription } from '@angular/forms'; @Component({ // 组件元数据保留原配置 }) export class YourComponent implements OnInit, OnDestroy { filteredOptions: any; options = []; serviceLogForm: FormGroup; private itemValueSub: Subscription; constructor(private fb: FormBuilder, private services: YourService) {} ngOnInit(): void { // 初始化表单 this.serviceLogForm = this.fb.group({ id: [0], Name: [], ArrayForm: this.fb.array([this.CreateArray()]) }); // 正确获取FormArray中的item控件 const arrayForm = this.serviceLogForm.get('ArrayForm') as FormArray; const firstItemGroup = arrayForm.at(0) as FormGroup; const itemControl = firstItemGroup.get('item'); // 订阅valueChanges(先判断控件是否存在) if (itemControl) { this.itemValueSub = itemControl.valueChanges.subscribe(response => { console.log('data is ', response); this.filterData(response); }); } // 提前加载数据 this.getData(); } CreateArray(): FormGroup { return this.fb.group({ item: [''] }); } filterData(enterData: string) { if (!enterData) { this.filteredOptions = [...this.options]; return; } this.filteredOptions = this.options.filter(item => { return item.toLowerCase().includes(enterData.toLowerCase()); }); } getData() { this.services.dataList(true).subscribe((response) => { this.options = response; this.filteredOptions = [...response]; console.log(response); }); } ngOnDestroy(): void { // 清理订阅,避免内存泄漏 if (this.itemValueSub) { this.itemValueSub.unsubscribe(); } } }
验证建议
- 启动项目后,检查控制台是否仍有空指针错误。
- 在输入框中输入内容,确认Mat AutoComplete面板能正常显示过滤后的匹配项。
内容的提问来源于stack exchange,提问作者Alluring
相关产品推荐
相关产品推荐

