Angular自定义单选按钮报NullInjectorError无NgControl提供者如何解决
问题解决方案
你的报错根因是继承了Angular内置的RadioControlValueAccessor类,但没有处理它的NgControl依赖,该类本身设计为配合Angular表单指令使用,默认需要注入NgControl实例,按以下两步修改即可修复:
1. 组件类补充依赖注入配置
修改radio-button.component.ts,给组件添加构造函数,用@Optional()装饰器标记NgControl为可选依赖,避免无表单上下文时抛出注入错误:
// 先导入必要的装饰器和类 import { Optional, Self, NgControl } from '@angular/forms'; @Component({ selector: 'fls-radio-button', templateUrl: './radio-button.component.html', styleUrls: ['./radio-button.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RadioButtonComponent), multi: true } ], encapsulation: ViewEncapsulation.None }) export class RadioButtonComponent extends RadioControlValueAccessor { @HostBinding('class') classes = 'fls-radio-button'; @Input() id: string; @Input() name: string; @Input() value: SimpleFieldValue; @Input() label: string; @Input() disabled = false; @Input() checked = false; // 新增构造函数 constructor(@Optional() @Self() ngControl: NgControl) { super(); if (ngControl) { ngControl.valueAccessor = this; } } setDisabledState(isDisabled: boolean): void { this.disabled = isDisabled; } }
如果你不想依赖Angular的表单上下文,也可以选择不继承RadioControlValueAccessor,自行完整实现ControlValueAccessor接口的所有方法,即可彻底消除NgControl依赖。
2. 单元测试调整
你现有测试是直接创建组件实例,没有模拟表单绑定的使用场景,补充构造函数的@Optional()装饰器后测试即可正常运行。如果需要模拟真实的表单使用场景,可以在测试中创建一个包装组件,用formControl或ngModel绑定你的单选按钮组件测试即可。
内容的提问来源于stack exchange,提问作者IonicMan
相关产品推荐
相关产品推荐

