Ответ 1
У ленивых загружаемых модулей есть своя собственная корневая область. Провайдеры, добавленные к ленивым загруженным модулям, получают экземпляр в этой корневой области вместо корневой области приложения. Если вы добавите поставщика в модуль, который не будет ленивым, будет создан только один экземпляр в корневой области приложения.
Почему услуга, предоставляемая в ленивом загруженном модуле, видима только для этого модуль?
В отличие от поставщиков модулей, загруженных при запуске, поставщики ленивые модули загружаются с модулями.Когда маршрутизатор Angular ленивый загружает модуль, он создает новый контекст выполнения. Этот контекст имеет свой собственный инжектор, который является прямым дочерний элемент инжектора приложения.
Маршрутизатор добавляет поставщиков ленивых модулей и поставщиков своих импортированные модули для этого дочернего инжектора.
Эти поставщики изолированы от изменений в поставщиках приложений с тем же токеном поиска. Когда маршрутизатор создает компонент внутри ленивый загруженный контекст, Angular предпочитает созданные экземпляры службы от этих поставщиков до экземпляров службы корневого приложения инжектор.
https://angular.io/docs/ts/latest/cookbook/ngmodule-faq.html#!#q-why-bad
Почему это плохо, если SharedModule предоставляет услугу ленивым загруженным модуль?
Этот вопрос возник в главе Angular Module, когда мы обсудили важность удержания провайдеров из SharedModule.Предположим, что мы указали UserService у поставщиков модулей (которые мы не). Предположим, что каждый модуль импортирует этот SharedModule (который они все делают).
При запуске приложения Angular загружает AppModule и ContactModule.
Оба экземпляра импортированного SharedModule предоставили UserService. Angular регистрирует один из них в корневом приложении инжектор (см. выше). Затем некоторый компонент вставляет UserService, Angular находит его в инжекторе корневого приложения, и предоставляет широкоэкранный синглтон UserService. Нет проблем.
Теперь рассмотрим HeroModule, который ленивый загружен!
Когда маршрутизатор ленивый загружает HeroModule, он создает дочерний инжектор и регистрирует провайдер UserService с этим дочерним инжектором. инжектор ребенка не является инжектором корня.
Когда Angular создает ленивый HeroComponent, он должен UserService. На этот раз он находит провайдера UserService в ленивом модульного дочернего инжектора и создает новый экземпляр UserService. Это совершенно другой экземпляр UserService, чем приложение singleton версии, которая Angular вводится в один из загруженных компоненты.
Это почти наверняка ошибка.
Докажите это себе. Запустите живой пример. Изменить SharedModule так что он предоставляет UserService, а не CoreModule. затем несколько раз переключаться между ссылками "Контакт" и "Герои". имя пользователя идет bonkers, поскольку Angular создает новый UserService каждый раз.
https://angular.io/docs/ts/latest/cookbook/ngmodule-faq.html#!#q-why-child-injector
Почему ленивая загрузка создает дочерний инжектор?
Angular добавляет @NgModule.providers к корневому инжектору приложения... если только модуль ленивый. Затем он создает дочерний инжектор и добавляет провайдеров модулей для дочернего инжектора.Это означает, что модуль ведет себя по-разному в зависимости от того, загружается во время запуска приложения или позже выполняется загрузка. Пренебрегая эта разница может привести к неблагоприятным последствиям.
Почему Angular не добавляет ленивых загружаемых поставщиков в инжектор корневого приложения как это делается для загруженных модулей? Почему непоследовательность?
Ответ обоснован в фундаментальной характеристике Angularсистема впрыска зависимостей. Инжектор может добавлять поставщиков, пока сначала используется. Как только инжектор начинает создавать и доставлять услуги, его список поставщиков заморожен. Никакие новые поставщики не разрешены.
Когда запускаются приложения, Angular сначала настраивает корень инжектор с поставщиками всех загруженных модулей до создавая свой первый компонент и вводя любой из предоставленных Сервисы. После запуска приложения инжектор корневого приложения закрывается новым провайдерам.
Время проходит. Логика приложения запускает ленивую загрузку модуля. Angular должен добавить поставщиков ленивого загруженного модуля к инжектору где-то. Он не может добавить их в инжектор корневого приложения, поскольку инжектор закрыт для новых поставщиков. Итак, Angular создает новый дочерний элемент инжектор для контекста ленивого загруженного модуля.