Угловой 6: предоставить HTTP_INTERCEPTORS для «корня» - PullRequest
0 голосов
/ 07 мая 2018

С переходом с Angular 5, где вы предоставляете сервис в AppModule, на Angular 6, где вы устанавливаете ключ 'provideIn' в декораторе @Injectable, я изменил все сервисы для использования нового метода "provideIn". Однако исключением является моя служба перехватчиков.

Как я могу предоставить токен HTTP_INTERCEPTORS для root и использовать InterceptorService?

это Angular 5, как я использую банкомат:

@Injectable()
export class InterceptorService implements HttpInterceptor {
...
}

в AppModule:

providers: [{
  provide: HTTP_INTERCEPTORS,
  useClass: InterceptorService,
  multi: true
}]

Но что будет Angular 6 way?

Я пробовал что-то вроде

@Injectable({
  provideIn: 'root',
  useValue: HTTP_INTERCEPTORS,
  deps: [forwardRef(() => InterceptorService)]
})
export class InterceptorService implements HttpInterceptor {
...
}

и множество других вариантов с Injectable, но не может понять, как заставить его работать без записи литерала объекта непосредственно в провайдеры модуля.

Ответы [ 3 ]

0 голосов
/ 18 мая 2018

In Interceptor

@Injectable()
export class InterceptorService implements HttpInterceptor {
...
}

В модуле приложения

providers: [{
  provide: HTTP_INTERCEPTORS,
  useClass: InterceptorService,
  multi: true
}]

"обеспечивается в ... сообщает Angular, что корневой инжектор отвечает за создание экземпляра [службы]. Услуги, предоставляемые таким образом, автоматически становятся доступными для всего приложения и не требуют перечислены в любом модуле. "

"Если поставщик не может быть настроен в декораторе @Injectable сервис, затем зарегистрируйте провайдеров приложений в корневом AppModule, а не в AppComponent. Как правило, регистрируйте поставщиков в NgModule, а не> в корневом компоненте приложения. "

Кроме того, если область обслуживания должна быть ограничена функцией или ветвью приложения, предоставьте эту услугу в компоненте верхнего уровня для этой ветви / функции

https://angular.io/guide/dependency-injection-in-action

0 голосов
/ 29 августа 2018

Здесь стоит отметить пару вещей:

1. providedIn: 'root' хорошая функция, но, вероятно, она не была создана для вас

Как упомянул @Leon, эта функция предназначена для того, чтобы сделать службы более доступными для дерева. Он не предназначен для полной замены с использованием свойства providers: [] модуля. Эта опция в основном предназначена для разработчиков библиотек, а не для разработчиков приложений.

Представьте себе этот сценарий:

Вы создали службу несколько месяцев назад, и теперь ваше приложение больше не использует ее. Вы знаете, что он не используется, потому что это ваше приложение, и у вас есть все знания и контроль над базой кода. Что вы делаете с этим сервисом?

A) Убедитесь, что он использует providedIn: 'root', чтобы Angular мог вытряхнуть его из связки, поскольку вы его больше не используете

Б) Удалить услугу.

Я думаю, B!

Представьте себе другой сценарий:

Вы используете сторонний модуль Angular из пакета npm. Этот модуль имеет 12 сервисов, которые вы можете использовать в своем приложении, чтобы воспользоваться его возможностями Ваше приложение не нуждается во всех этих функциях, поэтому вы добавляете только 3 из этих типов служб в компоненты или службы приложения.

Как вы решаете это?

A) Разветвите репозиторий, чтобы вы могли удалить все сервисы, которые ваше приложение не использует, поэтому вам не нужно включать их в ваш пакет.

B) Попросить владельца проекта использовать providedIn: 'root'. Если автор библиотеки использовал providedIn: 'root', сервисы, которые вы не используете, не влияют на размер вашего пакета, и они могут оставаться в пакете npm / модуле Angular для использования другими командами, если они в них нуждаются.

Я думаю, B!

2. providedIn: 'root' не работает для перехватчиков

Перехватчики - это служба multi DI-токена, что означает, что вы можете предоставить несколько значений для одного и того же DI-токена. Этот токен HTTP_INTERCEPTORS. Декоратор @Injectable({...}) не предоставляет API для предоставления декорированного типа для другого токена, как декоратор @NgModule({...}).

Это означает, что вы не можете сказать Angular Anywhere you would normally ask for 'HTTP_INTERCEPTORS' add this service to the set of values to use instead, используя @Injectable({...}) декоратор.

Это можно сделать только в @NgModule({...}) декораторе.

3. Предоставление перехватчиков зависит от заказа

Перехватчики - это конвейер, и порядок их предоставления влияет на определение порядка, в котором они получают доступ к объекту запроса (для изменения или проверки) и объекту ответа (для изменения или проверки).

Хотя некоторые перехватчики могут быть независимыми от порядка, вы все же, вероятно, захотите некоторого детерминизма в этом порядке.

Таким образом, даже если providedIn: 'root' работает для перехватчиков, порядок, в котором они будут предоставляться, будет определяться порядком разрешения типов на этапе компиляции Angular - вероятно, не то, что вам нужно.

Вместо предоставления их в массиве providers: [] в декораторе @NgModule({...}) вы можете явно указать порядок, в котором они будут вызываться.

0 голосов
/ 07 мая 2018

Свойство provideIn в Angular 6 является лишь дополнением к поведению в Angular 5. Если вы хотите предоставить что-то с уже существующим InjectionToken, вам все равно придется использовать синтаксис { provide: ClassA, useClass: ClassB }.

См. -> https://angular.io/guide/dependency-injection-in-action#external-module-configuration

ТЛ; др: Способ, которым вы предоставляете HTTP_INTERCEPTORS, не изменился в Angular 6, и нет пути "Angular 6".

...