Avec le changement de Angular 5 où vous fournissez un service dans AppModule à Angular 6 où vous définissez la clé 'supplyIn' dans @Injectable decorator, j'ai modifié tous les services pour utiliser la nouvelle méthode "supplyIn". Cependant, l'exception est mon service d'intercepteur.
Comment puis-je fournir le jeton HTTP_INTERCEPTORS pour 'root' et utiliser InterceptorService?
c'est la façon angulaire 5 que j'utilise atm:
@Injectable()
export class InterceptorService implements HttpInterceptor {
...
}
dans AppModule:
providers: [{
provide: HTTP_INTERCEPTORS,
useClass: InterceptorService,
multi: true
}]
Mais quelle serait la manière angulaire 6?
J'ai essayé quelque chose comme
@Injectable({
provideIn: 'root',
useValue: HTTP_INTERCEPTORS,
deps: [forwardRef(() => InterceptorService)]
})
export class InterceptorService implements HttpInterceptor {
...
}
et beaucoup d’autres variantes avec Injectable, mais il semble impossible de comprendre comment le faire fonctionner sans écrire un littéral d’objet directement dans les fournisseurs d’un module.
La propriété provideIn
- de Angular 6 n'est qu'un ajout au comportement de Angular 5. Si vous souhaitez fournir quelque chose avec un InjectionToken existant, vous devez toujours utiliser la syntaxe { provide: ClassA, useClass: ClassB }
.
Voir -> https://angular.io/guide/dependency-injection-in-action#external-module-configuration
tl; dr: La façon dont vous fournissez HTTP_INTERCEPTORS n’a pas changé dans Angular 6 et il n’existe pas de voie "Angular 6".
Dans l'intercepteur
@Injectable()
export class InterceptorService implements HttpInterceptor {
...
}
Dans le module d'application
providers: [{
provide: HTTP_INTERCEPTORS,
useClass: InterceptorService,
multi: true
}]
"providedIn ... indique à Angular que l'injecteur racine est responsable de créer une instance du [service]. Les services fournis de cette manière sont> automatiquement mis à la disposition de l'application entière et ne doivent pas nécessairement l'être énumérés dans n’importe quel module. "
"Si un fournisseur ne peut pas être configuré dans le décorateur @Injectable du service , Enregistrez les fournisseurs au niveau de l'application dans le AppModule racine, pas Dans le AppComponent. Généralement, enregistrez les fournisseurs dans le NgModule plutôt que> dans le> composant d'application racine. "
En outre, si la portée du service doit être limitée à une fonctionnalité ou à une branche de l'application, fournissez ce service au composant de niveau supérieur pour cette branche/fonctionnalité.
providedIn: 'root'
est une fonctionnalité intéressante, mais elle n'a probablement pas été conçue pour vousComme @Leon l'a mentionné, cette fonctionnalité vise à rendre les services plus faciles à manipuler. Il n'est pas destiné à remplacer complètement l'utilisation de la propriété providers: []
d'un module. C'est une option principalement destinée aux développeurs de bibliothèques, pas autant aux développeurs d'applications.
Vous avez créé un service il y a quelques mois et votre application ne l'utilise plus. Vous savez qu'il ne l'utilise pas parce que c'est votre application et que vous avez la connaissance et le contrôle total de la base de code. Que faites-vous à ce service?
A) Assurez-vous qu'il utilise providedIn: 'root'
pour que Angular puisse le faire sortir du paquet puisque vous ne l'utilisez plus.
B) Supprimer le service.
Je suppose que c'est B!
Vous utilisez un module angulaire tiers issu d'un package npm. Ce module contient 12 services différents que vous pouvez utiliser dans votre application pour tirer parti de ses fonctionnalités. Votre application n'a pas besoin de toutes ces fonctionnalités, vous n'injectez donc que 3 de ces types de service dans vos composants ou services d'application.
Comment résolvez-vous cela?
A) Branchez le référentiel afin de pouvoir supprimer tous les services que votre application n'utilise pas afin de ne pas avoir à les inclure dans votre bundle.
B) Demandez au propriétaire du projet d'utiliser providedIn: 'root'
. Si l'auteur de la bibliothèque a utilisé providedIn: 'root'
, les services que vous n'utilisez pas n'ont pas d'incidence sur la taille de votre paquet et peuvent rester dans le package npm/module Angular pour que les autres équipes puissent les utiliser s'ils en ont besoin.
Je suppose que c'est B!
providedIn: 'root'
ne fonctionne pas pour les intercepteursLes intercepteurs sont un service de jeton ID multi
, ce qui signifie que vous pouvez fournir plusieurs valeurs pour le même jeton ID. Ce jeton est HTTP_INTERCEPTORS
. Le décorateur @Injectable({...})
n'expose aucune API pour fournir le type décoré d'un jeton différent de celui utilisé par le décorateur @NgModule({...})
.
Cela signifie que vous ne pouvez pas indiquer Anywhere you would normally ask for 'HTTP_INTERCEPTORS' add this service to the set of values to use instead
angulaire à l'aide du décorateur @Injectable({...})
.
Vous ne pouvez le faire que dans un décorateur @NgModule({...})
.
Les intercepteurs sont un pipeline et l'ordre dans lequel ils sont fournis pour déterminer l'ordre dans lequel ils ont accès à l'objet de requête (modifier ou inspecter) et à l'objet de réponse (modifier ou inspecter).
Bien que certains intercepteurs puissent être agnostiques dans l’ordre, vous voulez probablement encore un certain déterminisme dans cet ordre.
Ainsi, même si providedIn: 'root'
fonctionnait pour les intercepteurs, l'ordre dans lequel ils seraient fournis serait déterminé par l'ordre de résolution des types lors de la compilation angulaire - probablement pas ce que vous voulez.
Au lieu de les fournir dans le tableau providers: []
dans un décorateur @NgModule({...})
, vous pouvez définir explicitement l'ordre dans lequel ils seront appelés.