Angular动态组件调用isValid方法时form属性未定义问题咨询
问题根因
- 偶发报错属于动态组件生命周期执行时序和组件实例存储时机不匹配导致的问题,不属于异步逻辑bug。
- Angular中动态组件通过组件工厂创建出实例后,
ngOnInit钩子要等到首轮变更检测执行完成才会触发,如果你是在组件实例刚创建完成就直接存入了WorkflowService的组件列表,此时如果用户在ngOnInit执行前触发了保存校验逻辑,就会出现form属性还未初始化的undefined报错。 - 另一种可能场景:已经被销毁的动态组件没有及时从服务的组件列表中移除,调用已销毁组件的
isValid方法时,form属性可能已经被回收。
修复方案
方案1:直接初始化FormGroup(推荐,改造成本最低)
不需要等到ngOnInit再赋值,直接在属性声明时完成初始化,组件实例创建完成后form就有值,从根源避免undefined:
// 直接在声明处初始化,不需要放到ngOnInit里 public form: FormGroup = new FormGroup({}); ngOnInit(): void { // 如果有需要动态添加的表单控件,再在这里做处理即可 }
方案2:校验方法加兜底判断
如果你的表单初始化必须依赖@Input传参或者其他只能在ngOnInit中拿到的数据,可以在isValid方法里加非空判断兜底:
public isValid(): boolean { // 表单未初始化时默认返回校验不通过,可根据业务需求调整返回值 if (!this.form) return false; const isValid: boolean = this.form.valid; if (isValid) { this.displayErrors = false; return true; } else { this.displayErrors = true; return false; } }
方案3:调整组件实例存入服务的时机
不要在组件刚创建完就存入服务,等到组件ngAfterViewInit钩子触发后再把实例添加到WorkflowService的组件列表,保证ngOnInit已经执行完成。同时在组件ngOnDestroy钩子中把实例从列表中移除,避免调用已销毁组件的方法:
// 动态组件中添加逻辑 ngAfterViewInit(): void { this.workflowService.addComponent(this); } ngOnDestroy(): void { this.workflowService.removeComponent(this); }
内容的提问来源于stack exchange,提问作者Jakub
相关产品推荐
相关产品推荐

