2016-09-21 61 views
2

当我想在角度2(rc6)中重用相同的基本组件时,我需要在扩展基本组件的所有构造函数中使用相同的依赖声明,否则依赖注入中断,因为它试图总是注入相同的依赖声明(我认为这是扩展基本组件的最后一个导入的组件)。当重用相同的基本组件时角度2依赖注入

例如,我有碱组分“动物成分”:

@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 {} 

最后我会加载t他在我的最后一个组件

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”)的提供者的名称,所有工作正常。

其他人有同样的问题?难道我做错了什么?

回答

1

今天我更新了我的angular2版本到最新的2.0.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 
     ); 

     //...