Angular从v9升级到v14后ComponentFactoryResolver与AbstractControlDirective报错求助
问题1:NgControl与AbstractControlDirective类型不兼容错误
原因:Angular升级后,MatFormField._control.ngControl的类型变为NgControl | AbstractControlDirective,无法直接赋值给NgControl类型变量。
解决方法:添加类型判断确保获取到的是NgControl实例,再执行后续逻辑:
ngAfterViewInit() { const controlDirective = this.formField._control.ngControl; // 类型守卫,仅当为NgControl实例时赋值并监听状态变化 if (controlDirective instanceof NgControl) { this.ngControl = controlDirective; this.ngControl.statusChanges.pipe( takeUntil(this.unsubscribe$) ).subscribe(_ => this.handleStatusChange()); } }
若你的业务场景中ngControl必然是NgControl(比如指令仅用于带表单控件的MatFormField),也可使用类型断言简化代码:
this.ngControl = this.formField._control.ngControl as NgControl;
问题2:ComponentFactoryResolver已废弃的替代方案
原因:Angular v10+开始推荐直接使用ViewContainerRef.createComponent创建组件,无需通过ComponentFactoryResolver解析工厂类。
解决方法:移除ComponentFactoryResolver依赖,直接用ViewContainerRef创建组件:
- 修改构造函数:
constructor( private viewContainerRef: ViewContainerRef, private formField: MatFormField, private elRef: ElementRef, private injector: Injector ) { }
- 修改
addErrors方法:
private addErrors(errors: Object) { const host = this.elRef.nativeElement.querySelector('.mat-form-field-subscript-wrapper'); // 直接传入组件类创建实例 this.componentRef = this.viewContainerRef.createComponent(FormErrorComponent, { injector: this.injector, hostElement: host }); this.componentRef.instance.errors = errors; this.componentRef.changeDetectorRef.detectChanges(); }
如果需要先清空容器再创建组件,可在createComponent前调用this.viewContainerRef.clear()。
内容的提问来源于stack exchange,提问作者Arter
相关产品推荐
相关产品推荐

