Angular2中@Input装饰器初始化属性的正确方式及值未更新问题排查
问题根因
报错本质是displayName执行时this上下文丢失,而非actions属性未同步:
- MatAutocomplete的
displayWith属性绑定的方法,会由Angular框架直接调用,默认不会绑定当前组件实例的上下文 - 因此
displayName中的this不再指向组件类,this.actions取值为undefined,调用.filter()时触发Cannot read property 'filter' of undefined报错 - 自动补全逻辑正常是因为
_filter方法在constructor的RxJS pipe内被调用,此时执行上下文仍绑定组件实例,能正常获取父组件传入的actions - 你之前排查时观察到
this.actions为空,实际是上下文丢失导致取不到组件属性,而非actions卡在初始值
修复方案
方案1:将displayName改为类箭头函数属性(推荐)
箭头函数的this在定义时就绑定当前组件实例,不会被调用方修改,同时增加防御性判断兼容actions异步加载的场景:
// 替换原有displayName方法 displayName = (id: number): string => { if (!id || !this.actions?.length) return ''; const targetAction = this.actions.find(action => action.id === id); return targetAction?.name ?? ''; }
优化点:用
find替代filter后取索引的写法,减少性能消耗,同时避免空值访问报错。
方案2:模板绑定displayWith时手动绑定this
如果不修改类方法写法,可在模板传参时显式绑定上下文:
<!-- mat-autocomplete的displayWith绑定处 --> [displayWith]="displayName.bind(this)"
同时需要在displayName方法内增加this.actions存在性判断,避免异步加载场景下的空值报错。
方案3:监听actions输入属性变化同步状态
如果父组件是异步加载actions,可实现OnChanges接口,在actions更新时主动触发过滤逻辑刷新:
import { OnChanges, SimpleChanges } from '@angular/core'; export class InputActionTypeaheadComponent implements ControlValueAccessor, OnChanges { // ...原有代码 ngOnChanges(changes: SimpleChanges): void { // 当actions输入属性更新时,重新触发一次表单值变更,刷新过滤结果 if (changes['actions'] && this.actionCtrl.value) { this.actionCtrl.setValue(this.actionCtrl.value, { emitEvent: true }); } } }
内容的提问来源于stack exchange,提问作者Greg
相关产品推荐
相关产品推荐

