У меня есть приложение Angular2
с service
, которое используется для получения данных из API. Следуя примеру this, я хочу создать отдельный файл, который должен содержать некоторые данные конфигурации. Моя проблема в том, что у моего сервиса есть декоратор @Injectable()
, и я не уверен, могу ли я передать ему массив provide
в метаданных, в которые я буду вводить конфигурацию, как показано в учебнике. Любой, кто когда-либо сталкивался с такой проблемой, может поделиться своим решением :)Angular2 - ввод в @Injectable
ответ
В самом деле, Angular2 использует иерархические инжекторы и форсунки связаны с компонентами. Короче говоря, вы можете определить поставщиков только по компонентам (providers
) или на уровне приложений (bootstrap
функция).
Что касается услуг, они смогут использовать поставщиков, которые видны для компонента, инициировавшего вызов, но вы не можете определить поставщиков на своих уровнях.
Вот пример:
Application
|
AppComponent
|
ChildComponent
getData() --- Service1 --- Service2
В таком применении, мы имеем три форсунки:
- инжектор приложения, который может быть сконфигурирован с использованием второго параметра функции
bootstrap
AppComponent
, который может быть сконфигурирован с использованием атрибутаproviders
этого компонента. Он может «видеть» элементы, определенные в инжекторе приложения. Это означает, что если провайдер не найден в этом провайдере, он автоматически будет искать этот родительский инжектор. Если он не найден в последнем случае, будет вызвана ошибка «поставщик не найден».- Инжектор
ChildComponent
, который будет следовать тем же правилам, что иAppComponent
. Чтобы вводить элементы, участвующие в цепочке впрыска, выполняемые для компонента, поставщики будут искать первый в этом инжекторе, затем вAppComponent
один и, наконец, в приложении один.
Это означает, что при попытке привнести Service1
в ChildComponent
конструктор, Angular2 будет выглядеть в ChildComponent
инжектор, затем в AppComponent
один и, наконец, в приложении один.
С Service2
должны быть введены в Service1
, та же обработка разрешения будет сделана: ChildComponent
инжектора, AppComponent
один и приложения один.
Это означает, что оба Service1
и Service2
могут быть определены на каждом уровне в соответствии с потребностями, используя атрибут providers
для компонентов, и второй параметр bootstrap
функции для инжектора приложения.
Этот ответ может помочь вам:
Это не поддерживается. Для услуг поставщики должны быть добавлены к bootstrap(AppComponent, [..., Service, ServiceDependency1, ...])
Смотрите также https://github.com/angular/angular/issues/5622
Это немного странно, но только компоненты могут настроить инъекции зависимостей в угловых (ну и bootstrap()
, но это по существу то же самое как корневой компонент). I.e, только компоненты могут указывать поставщиков.
Как отмечает @Thierry в своем ответе, каждый компонент в дереве компонентов получит связанный «инжектор», если указанный компонент имеет заданный массив providers
. Мы можем думать об этом как дерево инжектора, то есть (обычно много) более редкое, чем дерево компонентов. Когда необходимо разрешить зависимость, это дерево инжектора консультируется. Первый инжектор, который может удовлетворить зависимость, делает это. Дерево инжектора поднимается вверх к корневому компоненту/инжектору.
Таким образом, чтобы ваша служба вводила зависимость объекта конфигурации, этот объект конфигурации сначала должен быть зарегистрирован инжектором. I.e, в массиве providers
компонента, вызов provide(stringToken or OpaqueToken, {useValue: MyConfigObject})
Эта регистрация должна происходить где-то на уровне или над компонентом, в котором вы хотите использовать/внедрять вашу службу.
Ваш сервис должен тогда иметь @Inject
зарегистрированный объект конфигурации, потому что он найдет его в дереве инжектора.
Обратите внимание, что только компоненты могут настраивать поставщиков, декоратор @Injectable()
не поддерживает какие-либо параметры конфигурации, поэтому массив providers
не поддерживается.
Благодарим вас за ответ. К сожалению, я могу отметить только один как «Ответ», но ваш тоже достоин :) –
@RadoslavStoyanov, не проблема. Вначале DI может немного запутываться (пока вы не узнаете об инжекторном дереве), поэтому иногда несколько разных формулировок или объяснений могут помочь людям. Я хотел выделить часть дерева инжектора. –
- 1. Angular2: Подайте нон @Injectable класса
- 2. Избавьтесь от атрибута Injectable в angular2
- 3. В чем разница между функцией Angular2 @Injectable и non-инъекцией
- 4. Когда нам нужно использовать @Injectable для наших сервисов в Angular2?
- 5. HTTP PROVIDERS in @Injectable Service
- 6. Angular2 - ввод Singleton Service в Директиву
- 7. машинописный Angular2 Instantiation Injectable, такой как Http вне конструктора
- 8. Angular2: Unhandled Promise rejection: Нет провайдера для @Injectable
- 9. что такое diff в @Injectable() и @Inject
- 10. Угловой 2 Машинопись @injectable
- 11. Angular2 ES6 @ Ввод альтернативы
- 12. Ввод привязки свойств в Angular2
- 13. Angular2: Ввод привязки
- 14. angular2 пользовательские директивы ввод синтаксиса
- 15. Ввод данных для чисел в Angular2?
- 16. JMockit's @Injectable для неавторизованных полей
- 17. Angular 2 Http Service Injectable
- 18. angular2 Как мне получить отдельный подкласс `@ Injectable` в зависимости от платформы - кордовы или браузера?
- 19. Почему есть NPE в классе @Injectable
- 20. Angular2 Ввод вызова дважды по методу
- 21. объект обещают в angular2
- 22. Общая служба в Angular2
- 23. Написание инъекционной услуги в Angular2
- 24. Миграция из Angular2 бета1 в Angular2 beta15 - .map() ошибка
- 25. Использование $ jQuery в Angular2
- 26. Угловое 2 @Injectable() - как это работает
- 27. Передача переменной от @Injectable к компоненту
- 28. Angular2: DI Issue - Ввод услуги в другую службу приводит к неопределенной службе
- 29. Использование CanActivate с LazyLoaded Module и Injectable
- 30. Angular 2 @Injectable кажется, что не работает
Конечно, еще одна хорошая ссылка относительно возможностей DI в Angular 2 приведена здесь: http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html – Brocco