Есть ли способ внедрить службу в компонент из родительского компонента? - PullRequest
0 голосов
/ 25 февраля 2020

Итак, у меня есть компонент таблицы. Но компоненту таблицы нужно будет использовать соответствующую службу API в зависимости от того, вызывается ли она ComponentA или ComponentB.

Например, если ComponentB использует TableComponent, то он должен заставить TableComponent внедрить службу APIForB и использовать ее. заполнить таблицу.

Впервые на angular, поэтому не уверен, что такая возможность возможна.

Ответы [ 2 ]

1 голос
/ 25 февраля 2020

Итак, DI-система angular является иерархической , что означает, что:

сервисы являются единичными в объеме инжектора

И Angular будет создавать вложенные инжекторы с собственными экземплярами службы, всякий раз, когда он создает экземпляры компонентов, которые определяют providers в их @Component декораторе.

Для вас это означает, что вы можете предоставлять различные реализации служб для ваших компонентов, эти реализации служб должны расширять один и тот же абстрактный класс, и вы вводите абстрактный класс в свой 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

0 голосов
/ 25 февраля 2020

лучший способ для вас будет внедрить ваш родительский компонент и использовать его сервис. для облегчения инъекций и набора текста вы можете создать суперкласс для всех этих 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();
  }
}
...