有没有办法将服务从父组件注入组件?

时间:2020-02-25 07:54:56

标签: angular dependency-injection angular-services angular-components

所以我有一个表格组件。但是表组件将需要使用适当的API服务,具体取决于它是由ComponentA还是ComponentB调用。

例如,如果ComponentB使用TableComponent,则需要让TableComponent注入APIForB服务并使用它来填充表。

不熟悉角形,所以不确定是否有可能。

2 个答案:

答案 0 :(得分:1)

DI-system of angular is hierarchical表示:

服务是注入器范围内的单例

每当Angular创建在其providers装饰器中定义@Component的组件实例时,Angular就会使用自己的服务实例创建嵌套的注入器。

对于您来说,这意味着您可以为组件提供不同的服务实现,这些服务实现必须扩展相同的抽象类,然后将抽象类注入到TableComponent

APIService:

export abstract class APIService{
  yourMethod1:() => void ;
  ...
}

您必须将基类定义为抽象类而不是接口,因为接口在运行时不存在,因此它们不是有效的DI令牌。

APIforAService / APIforBService:

@Injectable()
export class APIforAService implements APIService{
  youMethod1Implementation(){...}
  ....
}

当然,您可以对APIforBService进行相同的操作,但实现方式有所不同。

TableComponent

现在您在TableComponent中注入了APIService,但未定义任何提供者!

@Component({
  selector: 'your-selector',
  templateUrl: '',
  providers: []
})
export class TableComponent {
  constructor(private apiService: APIService) {
  }
}

ComponentA / B

现在,在ComponentA和ComponentB中,您定义了适当的提供程序:

@Component({
  selector: 'componentA',
  templateUrl: '',
  providers: [{
    provide:APIService,
    useClass:APIforAService
  }]
})
export class ComponentA {

}

在这里,您也可以对ComponentB进行相同的操作,并使用APIforBService

由于采用了层次化的DI系统,因此,如果从TableComponent实例化,则APIforAService将得到ComponentA,如果从APIforBService实例化,则ComponentB

答案 1 :(得分:0)

对您来说最好的方法是注入父组件并使用其服务。为了简化注入和键入操作,您可以为所有这些TableContaiers创建一个超类

export abstract class TableContainer {
  constructor(public apiService: SomeServiceTypeIfYouHaveIt) {};
}
..................
@Component({
...,
providers: [{provide: TableContainer, useExisting: ComponentA}]
})
export class ComponentA extends TableContainer {
   constructor(service: MyService){ super(service); }
} 
..................
export class TableComponent {
  constructor(private parent: TableContainer) {}

  apiCall() {
    this.parent.apiService.doSmth();
  }
}
相关问题