2016-02-23 2 views
4

У меня есть приложение Angular2 с service, которое используется для получения данных из API. Следуя примеру this, я хочу создать отдельный файл, который должен содержать некоторые данные конфигурации. Моя проблема в том, что у моего сервиса есть декоратор @Injectable(), и я не уверен, могу ли я передать ему массив provide в метаданных, в которые я буду вводить конфигурацию, как показано в учебнике. Любой, кто когда-либо сталкивался с такой проблемой, может поделиться своим решением :)Angular2 - ввод в @Injectable

ответ

5

В самом деле, 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 функции для инжектора приложения.

Этот ответ может помочь вам:

+2

Конечно, еще одна хорошая ссылка относительно возможностей DI в Angular 2 приведена здесь: http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html – Brocco

2

Это немного странно, но только компоненты могут настроить инъекции зависимостей в угловых (ну и bootstrap(), но это по существу то же самое как корневой компонент). I.e, только компоненты могут указывать поставщиков.

Как отмечает @Thierry в своем ответе, каждый компонент в дереве компонентов получит связанный «инжектор», если указанный компонент имеет заданный массив providers. Мы можем думать об этом как дерево инжектора, то есть (обычно много) более редкое, чем дерево компонентов. Когда необходимо разрешить зависимость, это дерево инжектора консультируется. Первый инжектор, который может удовлетворить зависимость, делает это. Дерево инжектора поднимается вверх к корневому компоненту/инжектору.

Таким образом, чтобы ваша служба вводила зависимость объекта конфигурации, этот объект конфигурации сначала должен быть зарегистрирован инжектором. I.e, в массиве providers компонента, вызов
provide(stringToken or OpaqueToken, {useValue: MyConfigObject})
Эта регистрация должна происходить где-то на уровне или над компонентом, в котором вы хотите использовать/внедрять вашу службу.

Ваш сервис должен тогда иметь @Inject зарегистрированный объект конфигурации, потому что он найдет его в дереве инжектора.

Обратите внимание, что только компоненты могут настраивать поставщиков, декоратор @Injectable() не поддерживает какие-либо параметры конфигурации, поэтому массив providers не поддерживается.

+0

Благодарим вас за ответ. К сожалению, я могу отметить только один как «Ответ», но ваш тоже достоин :) –

+1

@RadoslavStoyanov, не проблема. Вначале DI может немного запутываться (пока вы не узнаете об инжекторном дереве), поэтому иногда несколько разных формулировок или объяснений могут помочь людям. Я хотел выделить часть дерева инжектора. –

Смежные вопросы