当我想在angular 2(rc6)中重用相同的基本组件时,我需要在扩展基本组件的所有构造函数中使用相同的依赖声明,否则依赖注入会因为尝试注入始终相同而中断依赖项声明(我认为这是扩展基本组件的最后一个导入组件)。
例如,我有基本组件“AnimalComponent”:
@Component({
selector: '#animalComponent',
template: `I'm a animal component`
})
export class AnimalComponent
{
constructor(
@Inject('AnimalData') protected _data: any
) {}
}
我将基本组件扩展为两个组件“CatComponent”和“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
);
}
}
然后我将组件包装在模块中,因此我可以在运行时加载它们
@NgModule({
imports: [CommonModule],
declarations: [CatComponent],
exports: [CatComponent]
})
export class CatModule {}
@NgModule({
imports: [CommonModule],
declarations: [DogComponent],
exports: [DogComponent]
})
export class DogModule {}
最后我将在最终组件中加载两个组件
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, []);
}
);
}
}
在这个虚拟的情况下,当尝试解决“DogComponent”的依赖注入时,组件注入将被破坏,消息:“没有CatData的提供者!”但是,如果我更改同名提供者的名称(“AnyAnimalData”而不是“CatData”和“DogData”),则一切正常。
有其他人有同样的问题吗?我做错了吗?
答案 0 :(得分:1)
今天我将angular2版本更新到最新版本2.0.1,不幸的是问题仍然存在。为了多次重复使用相同的基本组件避免角度注入的问题,我在这里留下了我的解决方案,以防对某人有用。
1-创建一个可以扩展的组件副本,并将其重命名为“[my-component] .extension-component.ts”,然后从构造函数中声明所有变量并将构造函数重命名为“init”,在init方法中,将所有变量作为参数接收,并将每个变量分配给相应的声明变量。
@Component({
selector: 'myComponent',
template: ''
})
export abstract class MyComponentExtensionComponent
{
// Contructor vars
protected _var1: type1;
protected _var2: type2;
protected _varN: typeN;
// Local vars
protected _varZ: typeZ;
/**
* Initialization of component (replace the original constructor to avoid angular injection inheritance problem)
* @param var1
* @param var2
* @param varN
*/
public init(
var1: type1,
var2: type2,
varN: typeN
) {
// Constructor vars
this._var1 = var1;
this._var2 = var2;
this._varN = varN;
// Local vars
this._varZ = "I'm a var Z";
}
//...
}
2-现在,您可以多次扩展此组件,而不会出现任何问题:
//...
import {MyComponentExtensionComponent} from './my-component.extension-component';
//...
export class MyChildComponent extends MyComponentExtensionComponent
{
constructor(
var1: type1,
var2: type2,
varN: typeN
) {
// Call parent
super();
super.init(
var1,
var2,
varN
);
//...