为Component提供依赖于组件@Input的服务实例

时间:2017-11-01 16:46:12

标签: angular input service dependency-injection

我有一个包含子网格和细节组件的Master-Detail组件。

基于@Input entityType参数,网格和详细信息组件需要将其特定的dataService属性初始化为DataService1,DataService2,...或DataServiceN。 实现这一目标的最佳方法是什么?我看到了各种可能性:

  1. 使用@Injectable方法创建createServiceInstance(entityType)工厂服务:

    public createService(type: EntityType): any {
        switch (type) {
            case EntityType.Type1:
                return new DataService1();
            case EntityType.Type2:
                return new DataService2();
            case EntityType.TypeN:
                return new DataServiceN();
        }
    }
    

    然后将该服务注入Master-Detail Component构造函数并指定do

    this.dataService = this.factoryService.createService(entityType)
    
    在ngOnInit / ngOnChanges中

    。然后,我们将@Input dataService添加到网格和详细信息组件,并将其绑定到masterDetail dataService属性。

  2. 在详细/网格组件中使用Injector服务,将@Component装饰器的providers属性设置为[DataService1,DataService2,...,DataServiceN],然后在ngOnInit中

    this.dataService = this.injector.get(getDataService(entityType))
    

    export function getDataService(entityType: string): any {
        switch (type) {
            case EntityType.Type1:
                return DataService1;
            case EntityType.Type2:
                return DataService2;
            case EntityType.TypeN:
                return DataServiceN;
        }
    }
    
  3. 使用1)和2)的混合:在其构造函数中提供ServiceFactory和[DataService1,DataService2,...,DataServiceN],然后在详细信息/ grid component ngOnInit do

    this.dataService = this.factoryService.getDataService(entityType)
    

    getDataService(entityType: string): any {
        switch (type) {
            case EntityType.Type1:
                return this.dataService1;
            case EntityType.Type2:
                return this.dataService2;
            case EntityType.TypeN:
                return this.dataServiceN;
        }
    }
    
  4. 另一种解决方案?

  5. 我正在使用带有TypeScript的Angular 4。

1 个答案:

答案 0 :(得分:0)

我遇到了类似的问题,并找到了以下可行的解决方案:

我有FileService界面:

export interface FileService {
    downloadDocument(ownerId: string, fileId: string): Observable<any>;
}

然后,我将所有可能的服务实现此接口。在子组件中,我有一个输入:

export class SomeTestComponentComponent {

    @Input() fileService: FileService;

    download() {
        console.log(this.fileService);
        // this.fileService.download(...);
    }

}

现在在父组件中,我可以决定在此组件实例中应使用哪种服务:

<app-some-test-component [fileService]="fileServiceImpl" ></app-some-test-component>

这种方法意味着您无需提供字符串来决定要使用的服务,而是提供服务本身。