如何通过通用指令修改Angular抽象组件的@Input属性?
解决方案
要解决抽象类注入的问题,核心是为抽象类添加依赖注入支持,并让每个子类组件提供对应的实例令牌,具体步骤如下:
1. 为抽象类添加@Injectable()装饰器
Angular无法直接注入未标记为可注入的抽象类,因此需要给AbstractControlComponent添加@Injectable()装饰器:
@Injectable() @Directive() export abstract class AbstractControlComponent<T> implements ControlValueAccessor { ... @Input() warnings: string[] = []; ... }
2. 在子类组件中提供抽象类的实例令牌
每个继承自AbstractControlComponent的子组件,需要在自身的providers数组中注册抽象类的提供者,用useExisting指向当前组件实例,这样Angular就能找到对应注入对象:
修改InputComponent
@Component({ selector: 'test-input', templateUrl: './input.component.html', styleUrls: ['./input.component.scss'], providers: [ { provide: AbstractControlComponent, useExisting: InputComponent } ] }) export class InputComponent extends AbstractControlComponent<string> { }
修改DatepickerComponent
@Component({ selector: 'test-datepicker', templateUrl: './datepicker.component.html', styleUrls: ['./datepicker.component.scss'], providers: [ { provide: AbstractControlComponent, useExisting: DatepickerComponent } ] }) export class DatepickerComponent extends AbstractControlComponent<Date> { }
3. 验证指令的注入逻辑保持不变
此时你的ValidationDirective中注入AbstractControlComponent的代码可以正常运行,无需修改:
@Directive({ selector: '[validation]', }) export class ValidationDirective { constructor( private readonly control: NgControl, @Host() readonly component: AbstractControlComponent<any> ) {} ngOnInit(): void { this.component.warnings = ['test1', 'test2']; } }
这样既保证了指令的通用性,无需依赖具体组件类,又解决了注入找不到提供者的问题。
内容的提问来源于stack exchange,提问作者isy
相关产品推荐
相关产品推荐

