@Injectable () декоратор и массив провайдеров - PullRequest
0 голосов
/ 24 февраля 2020

Служба, которая предоставляется в "root" в декораторе @Injectable (), все еще должна быть в массиве поставщиков модуля?

Документация Angular на самом деле не дает мне ответа, или я не совсем понимаю его.

Внутри моей основной папки есть служба аутентификации, которая предоставляется в root. Я не хочу импортировать мой основной модуль внутри модуля приложения, чтобы использовать все предоставляемые сервисы и компоненты.

Нужно ли дополнительно настраивать сервис в массиве provider модуля или Достаточно того, что оно уже предоставлено на уровне root с использованием декоратора?

Ответы [ 2 ]

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

Служба, которая предоставляется в "root" в декораторе @Injectable (), все еще должна быть в массиве поставщиков модуля?

Нет!

Когда вы создаете сервис с помощью Angular CLI, я считаю, что providedIn: "root" добавляется по умолчанию, поэтому технически вам никогда не нужно добавлять одну из ваших собственных служб в массив провайдеров.

Нужно ли дополнительно настраивать службу в массиве поставщиков модуля или достаточно того, что она уже предоставляется на уровне root с использованием декоратора?

Достаточно того, чтобы оно предоставлялось на уровне root с использованием декоратора.

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

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

Точки в предоставленной вами ссылке - это разные методы регистрации сервисов, от наименее заданных c до наиболее специфицированных c.

Спецификаций приложений c - используйте @Injectable({ providedIn: 'root' })

Когда вы предоставляете услугу на уровне root, Angular создает один общий экземпляр HeroService и внедряет его в любой класс, который его запрашивает. Регистрация провайдера в метаданных @Injectable () также позволяет Angular оптимизировать приложение, удаляя службу из скомпилированного приложения, если оно не используется.

Спецификация модуля c - зарегистрироваться в поставщиках модулей

Когда вы регистрируете поставщика с указанным c NgModule, один и тот же экземпляр службы доступен для всех компонентов в этом NgModule. Чтобы зарегистрироваться на этом уровне, используйте свойство provider декоратора @NgModule (),

Component-speci c - зарегистрироваться в компоненте

Когда вы регистрируете Поставщик на уровне компонента, вы получаете новый экземпляр службы с каждым новым экземпляром этого компонента. На уровне компонентов зарегистрируйте поставщика услуг в свойстве метаданных @Component ().

Все приведенные выше цитаты взяты из официальной страницы Введение в службы и внедрение зависимостей

  • Если у вас есть только один модуль, то первые два метода эквивалентны и должны использовать только один метод. go проще с @Injectable - подходом CLI по умолчанию.
  • Если вы хотите разделить экземпляры службы между несколькими модулями, используйте первый метод.
  • Если вам нужен один экземпляр для каждого независимого модуля, используйте второй подход.
  • Если вы хотите поделиться экземпляром для всего приложения со всеми компонентами, кроме одного, тогда используйте первый подход в дополнение к Третий подход для одного аномального компонента.

По моему мнению, большинство вариантов использования подпадают под первые два подхода.

Регистрация специфицированных модулей c services

Совет: просто используйте providedIn: 'root'. Неиспользуемые сервисы не будут скомпилированы для модуля, если он не используется из-за тряски дерева. Объявление специфичных для модуля c сервисов кажется избыточным и, как мы увидим, может вызвать проблемы.

Существует два способа регистрации специфичных для модуля c сервисов - либо из модуля, либо из сервиса.

module

@NgModule({
  providers: [MyService]
})
export class MyModule {}

service

@Injectable({ providedIn: MyModule })

Последний является официально рекомендуемым подходом. Объявление массива провайдеров - это похмелье с более ранних дней.

С документов :

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

Почему вы должны просто использовать providedIn: 'root'

Итак, мы видим, что этот подход потрясает дерево. Все идет нормально. Но вы получите циклические ссылки, если просто попытаетесь импортировать тот же модуль, в котором объявлены компоненты, использующие клиенты.

Возьмите эту настройку:

my-module

declarations: [
  MyComponent
]

my-service

@Injectable({ providedIn: MyModule })

my-component

constructor(private myService: MyService) {}
  • my-service импортирует my-module
  • my-module импортирует my -component
  • my-component import my-service

Существует круговая зависимость.

Обходной путь для этого - создать сервисный модуль и импортировать его в ваш модуль.

my-module

imports: [
  MyModuleServices
],
declarations: [
  MyComponent
]

my-module-services


my-service

@Injectable({ providedIn: MyModuleServices })

my-component

constructor(private myService: MyService) {}

Это очень многогранная альтернатива простому использованию providedIn: 'root' и позволению сотрясению дерева работать.

...