为 Component 提供一个依赖于组件 @Input 的服务实例
Posted
技术标签:
【中文标题】为 Component 提供一个依赖于组件 @Input 的服务实例【英文标题】:Provide Component with a service instance that depends on component @Input 【发布时间】:2018-04-14 01:24:21 【问题描述】:我有一个包含子网格和细节组件的主从组件。
基于@Input entityType 参数,网格和细节组件将需要将其特定的dataService 属性初始化为DataService1、DataService2、...或DataServiceN。 实现这一目标的最佳方法是什么?我看到了各种可能性:
使用createServiceInstance(entityType)
方法创建@Injectable
工厂服务:
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 组件构造函数并分配 do
this.dataService = this.factoryService.createService(entityType)
在 ngOnInit / ngOnChanges 中。然后我们将@Input dataService 添加到grid 和detail 组件,并将其绑定到masterDetail dataService 属性。
在细节/网格组件中使用 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;
使用 1) 和 2) 的组合:在其构造函数中为 ServiceFactory 提供 [DataService1, DataService2, ..., DataServiceN],然后详细/网格组件 ngOnInit 执行
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;
另一种解决方案?
我正在使用带有 TypeScript 的 Angular 4。
【问题讨论】:
没有客观标准,就没有“最佳方式”。您尝试过其中一种吗?怎么样? 我尝试了解决方案 1 和 2,两者都很好,但更多的是关于代码质量和最佳实践。例如,我不喜欢我们使用 new() 实例化服务并在解决方案 1) 的主从组件中保留引用的事实。在解决方案 2) 中,我们直接在 master-detail 内提供所有服务,这也是我不想拥有的某种形式的耦合。这就是为什么我认为第三个选项可能是一个不错的选择,但我可能会忽略其他一些可能性 【参考方案1】:我遇到了类似的问题,并找到了以下可行的解决方案:
我有接口文件服务:
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>
这种方法意味着您不提供字符串来决定使用哪个服务,而是提供服务本身。
【讨论】:
以上是关于为 Component 提供一个依赖于组件 @Input 的服务实例的主要内容,如果未能解决你的问题,请参考以下文章
如何将依赖于 Styled Components 的 React 组件库提供给另一个也具有 Styled Comopnents 依赖项的库?