So, the actual problem: sometimes we have many similar components in our project, with the same logic, the same DI, properties, etc. inherit? In fact, the thought is good, the DRY principle is observed, we have one source of truth, when changing that same general logic, you will not have to jump over all the components, etc.
But there is one caveat: these unfortunate designers. It is necessary in each inherited component to pass all DIs to the parent's constructor.
constructor (
customService: CustomService,
additionalService: AdditionalService
) {
super(customService, additionalService)
}
looks not very good, but it's not bad. The trouble is that if we add DI in the base class, we will have to jump over all the inherited components and add this dependency to the constructor. Our DRY was crying :-))
Let's try to do it differently: together with the base component, we will create an Injectable class, where we will wrap all the dependencies. And inject it into the base class
@Injectable()
export class MyBaseComponentDependences {
constructor(
public customService: CustomService,
public additionalService: AdditionalService
) {}
}
@Directive()
export abstract class MyBaseComponent<T> {
//
shareEntity = this.deps.additionalService.getShare()
protected constructor(
public deps: MyBaseComponentDependences
) {}
}
The inherited class will look like this
@Component({providers: [MyBaseComponentDependences] })
export class MyChildComponent extends MyBaseComponent<MyDto> {
// -
customEntity = this.deps.customService.getEntity()
constructor(deps: MyBaseComponentDependences) {
super(deps);
}
}
Now, if DI is added to the base class, we only change the MyBaseComponentDependences class, everything else remains as it is. Problem solved
PS: however, I believe that component inheritance in Angular should be used only when it is really necessary, and it is not possible or advisable to transfer the general logic to services, separate classes or attribute directives.