3.
Dependency Injection является иерархическим
bootstrap()
|-app-component
|-sub-component1
|-sub-component2
|-sub-sub-component21
Когда компонент или служба инстанцирован по углам главного DI, он проверяет, какие параметры конструктор ожидает и старается выглядеть вверх соответствующий провайдер.
При создании sub-sub-component
у него есть такой конструктор, как constructor(myService: MyService)
, DI начинает поиск от sub-sub-components
провайдеров вверх, если найдет подходящего поставщика. Если он достигает `bootstrap() и до сих пор не найден, он не может получить сообщение об ошибке.
Для каждого уровня в иерархии создается только один экземпляр провайдера. Когда MyService
зарегистрирован как поставщик в bootstrap()
, тогда любой компонент, который запрашивает MyService
, будет передан в том же экземпляре, созданном в bootstrap()
.
Когда MyService
является также зарегистрирован в sub-component2
, а затем, когда sub-sub-component
запрашивает MyService
он получит один из sub-component2
, потому что это первый находит. Когда sub-component1
также запросит MyService
, DI вернет один из bootstrap()
, потому что в иерархии вверх нет ничего, кроме MyService
.
Если вы хотите поделиться некоторыми данными со всем приложением, зарегистрируйте только тот сервис, который вы хотите использовать, для совместного использования данных по адресу bootstrap()
.
1.
Если компонент ('субкомпонент') имеет конструктор как
export class SubComponent {
constructor(private myService: MyService) {
}
someName: string;
clickHandler($event) {
this.myService.clickHappended = true;
this.someName = this.myService.loadNameFromServer();
}
}
затем ссылка на MyService
присвоенного myService
и кода SubComponent
может читать и писать поля MyServices
и вызывать его методы.
4. И если someComponent вводят someService, в котором впрыскивается someService2, мне нужно, чтобы установить в качестве поставщика оба [someService, someService2] на уровне someComponent? И если я уже внедряю someService2 someere или/и в компонент верхнего уровня?
Когда класс компонента или класс обслуживания создается Угловым, он использует DI. Он ищет поставщиков для запрашиваемого типа и создает экземпляр или использует существующий. Когда DI создает экземпляр, он проверяет конструкторы этого типа и снова ищет поставщиков для этих типов. Это происходит рекурсивно на произвольных уровнях (даже в циклах, когда DI нуждается в некоторой помощи)
Итак, короткий ответ: да. Все, что вводится DI, требует зарегистрированного поставщика.
5. Почему HTTP_PROVIDERS до Сета в бутстраповской уровне?
Классы, предоставляемые HTTP_PROVIDERS
, могут быть повторно использованы всем приложением. Нет необходимости создавать новый экземпляр для каждого HTTP-запроса и не нужно, чтобы каждый компонент или служба имел свой собственный экземпляр класса Http
. Если вы хотите, чтобы конкретный компонент использовал другой класс Http
, вы можете добавить этот конкретный класс Http
в список поставщиков этого компонента. Этот компонент и все его подкомпоненты будут использовать этот провайдер.
export class MySpecialHttp {
}
@Component(selector: 'sub-sub',
providers: [provide(Http, {useClass: MySpecialHttp})]
export class SubSubComponent {
constructor(http: Http) {}
}
Здесь мы поручаем DI, которые при SubSubComponent
или один из его дочерних компонентов-запросы Http
, проходят в MySpecialHttp
вместо.