Angular中filteredOptions与@ViewChild变量的规范初始化方法
Angular类属性正确初始化方案
针对你提到的两个属性,不需要用@ts-ignore屏蔽校验,按照TypeScript和Angular的语法规范处理即可:
1. filteredOptions: Observable<Options[]> 初始化
这个属性是你自己在组件初始化阶段赋值的流,有两种合规写法:
- 推荐写法:声明时直接初始化,把
ngOnInit里的流定义逻辑移到属性声明处,类型完全匹配,不会有TS报错:
// 删掉ngOnInit里对filteredOptions的赋值,直接声明时初始化 filteredOptions: Observable<Options[]> = this.autoSelectFormControl.valueChanges.pipe( startWith(''), map((value) => this._filter(value || '')) );
- 如果你坚持要在
ngOnInit里赋值,使用TypeScript的**明确赋值断言符!**即可,这是专门用来标记“属性会在构造后、首次使用前完成赋值”的语法,比@ts-ignore安全得多,不会屏蔽其他类型错误:
filteredOptions!: Observable<Options[]>;
2. @ViewChild('auto') autocomplete: MatAutocomplete 初始化
@ViewChild装饰的属性是Angular在视图初始化完成(ngAfterViewInit生命周期执行)时自动赋值的,这类属性的标准处理方式:
- 官方推荐写法:同样用明确赋值断言符
!,这是Angular官方文档示例中对ViewChild属性的通用写法:
@ViewChild('auto') autocomplete!: MatAutocomplete;
你当前把autocomplete的调用逻辑放在onBlur事件中是安全的——blur事件触发时视图早就完成初始化,不会出现属性为undefined的情况。
- 如果要做最严格的空值保护,可以声明为可选属性,在调用时加空值判断,完全不需要任何TS忽略指令:
@ViewChild('auto') autocomplete?: MatAutocomplete; onBlur = () => { if (!this.autocomplete?.isOpen) { const hasValidOption = this.options.some(item => item.key === this.autoSelectFormControl.value); if (!hasValidOption) { this.autoSelectFormControl.setValue(''); } } };
注意事项
不要手动给@ViewChild属性赋值空对象、伪造实例作为默认值,Angular会在视图渲染后自动覆盖该属性,手动伪造的默认值反而可能导致生命周期早期拿到错误实例、类型不匹配的问题。
另外你当前的onBlur逻辑可以按上面示例简化,去掉冗余的三目返回null的写法,可读性更高。
内容的提问来源于stack exchange,提问作者Van Wilder
相关产品推荐
相关产品推荐

