When I want to reuse the same base component in angular 2 (rc6), I need to use the same declaration of dependencies in all constructors that extends the base component, otherwise the dependency injection breaks because it tries to inject always the same dependencies declaration (I think that is the last imported component that extends the base component).
For example, I have the base component "AnimalComponent":
@Component({
selector: '#animalComponent',
template: `I'm a animal component`
})
export class AnimalComponent
{
constructor(
@Inject('AnimalData') protected _data: any
) {}
}
I extend the base component in two components "CatComponent" and "DogComponent"
@Component({
selector: '#catComponent',
template: `I'm a cat component`
})
export class CatComponent extends AnimalComponent
{
constructor(
@Inject('CatData') data: any
) {
super(
data
);
}
}
@Component({
selector: '#dogComponent',
template: `I'm a dog component`
})
export class DogComponent extends AnimalComponent
{
constructor(
@Inject('DogData') data: any
) {
super(
data
);
}
}
then I wrap both the component in modules, so I can load them at run-time
@NgModule({
imports: [CommonModule],
declarations: [CatComponent],
exports: [CatComponent]
})
export class CatModule {}
@NgModule({
imports: [CommonModule],
declarations: [DogComponent],
exports: [DogComponent]
})
export class DogModule {}
and finally I will load the two components in my final component
import {DogModule} from './dog.module';
import {CatModule} from './cat.module';
@Component({
selector: '#mainComponent',
template: `
I'm a main component
<template #catComponent></template>
<template #dogComponent></template>
`
})
export class MainComponent
{
@ViewChild('catComponent', {read: ViewContainerRef}) catView: ViewContainerRef;
@ViewChild('dogComponent', {read: ViewContainerRef}) dogView: ViewContainerRef;
constructor(
protected _injector: Injector,
protected _compiler: Compiler
) {
let catInjector = ReflectiveInjector.fromResolvedProviders(
ReflectiveInjector.resolve({provide: 'CatData', useValue: 'Some cat information'}),
this._injector
);
this._compiler.compileModuleAndAllComponentsAsync(CatModule).then(
moduleFactory => {
let compFactory = moduleFactory.componentFactories.find(tmpCompFactory => tmpCompFactory.componentType.name === 'CatComponent');
let componentRef = this.catView.createComponent(compFactory, 0, catInjector, []);
}
);
let dogInjector = ReflectiveInjector.fromResolvedProviders(
ReflectiveInjector.resolve({provide: 'DogData', useValue: 'Some dog information'}),
this._injector
);
this._compiler.compileModuleAndAllComponentsAsync(DogModule).then(
moduleFactory => {
let compFactory = moduleFactory.componentFactories.find(tmpCompFactory => tmpCompFactory.componentType.name === 'DogComponent');
let componentRef = this.dogView.createComponent(compFactory, 0, dogInjector, []);
}
);
}
}
In this dummy case, the component injection will be broken when try to resolve the dependency injection of the "DogComponent" whit the message: "No provider for CatData!" However if I change both the names of providers for the same name ("AnyAnimalData" instead of "CatData" and "DogData") all works fine.
Someone else with the same problem? Am I doing something wrong?