1. Le lien doc officiel pour l'injection de dépendances
Angulaire https://angular.io/guide/dependency-injection
Denpendency Injection, ou DI, est l'un des concepts fondamentaux d'Angular. DI est écrit par un framework angulaire et permet aux classes avec des décorateurs angulaires, tels que les composants, les directives, les Piples et les Injectables , de configurer les dépendances dont elles ont besoin.
Il existe deux rôles principaux dans le système DI : consommateur de dépendances et fournisseur de dépendances.
2. @Injectable
Une classe angulaire ou une autre définition qui fournit une dépendance à l'aide d'un mécanisme d'injection de dépendances. Une classe de service injectable doit être marquée par le décorateur @Injectable. D'autres éléments, tels que des valeurs constantes, peuvent également être injectables.
Il existe une option pour le décorateur @Injectable, qui est "provideIn?".
Option | Description |
---|---|
Fourni dans? | Détermine quels injecteurs fourniront le produit injectable. |
Il a principalement 5 valeurs pour différents scénarios :
provideIn? : Tapez <any> | 'racine' | 'plateforme' | 'n'importe lequel' | nul
Mais "Type<any>" et "any" sont DEPRECATED .
- 'null' : équivalent à indéfini. L'injectable n'est fourni automatiquement dans aucune portée et doit être ajouté à un tableau de fournisseurs d'un @NgModule, @Component ou @Directive.
- « root » : l'injecteur au niveau de l'application dans la plupart des applications.
- « plateforme » : un injecteur de plate-forme singleton spécial partagé par toutes les applications de la page.
L'exemple suivant montre qu'une classe de service est correctement marquée par @Injectable afin qu'un service de prise en charge puisse être injecté lors de la création.
@Injectable()
class UsefulService {
}
@Injectable()
class NeedsService {
constructor(public service: UsefulService) {}
}
const injector = Injector.create({
providers:
[{provide: NeedsService, deps: [UsefulService]}, {provide: UsefulService, deps: []}]
});
expect(injector.get(NeedsService).service instanceof UsefulService).toBe(true);
3. Assurer la dépendance
Une dépendance fournissante doit être marquée par le décorateur @Injectable(), voyons le décorateur @Injectable.
La première étape consiste à ajouter le décorateur @Injectable pour montrer que la classe peut être injectée :
@Injectable()
class HeroService {}
L'étape suivante consiste à le rendre disponible dans le DI en le fournissant. Une dépendance peut être prévue à plusieurs endroits :
- Au niveau du composant, en utilisant le champ fournisseurs du décorateur @Component. Dans ce cas, le HeroService devient disponible pour toutes les instances de ce composant et d'autres composants et directives utilisés dans le modèle, par exemple :
@Component({
selector: 'hero-list',
template: '...',
providers: [HeroService]
})
class HeroListComponent {}
Lorsque vous enregistrez un fournisseur au niveau du composant, vous obtiendrez une nouvelle instance du service avec chaque nouvelle instance de ce composant.
- Au niveau de l'application, il existe deux manières de définir un fournisseur. celui réalisé par @NgModule dans le domaine des fournisseurs.
@NgModule({
declarations: [HeroListComponent]
providers: [HeroService]
})
class HeroListModule {}
L'autre méthode est réalisée par le décorateur @Injectable, il suffit de renseigner la valeur 'root' dans l'option "provideIn":
@Injectable({
providedIn: 'root'
})
class HeroService {}
notez que cette méthode convient à une instance d'un projet, mais si vous souhaitez que chaque composant ait une nouvelle instance, la première méthode est un bon choix.
4. Injection d'une dépendance
Il existe deux façons d'injecter une dépendance dans angulaire, l'une est d'utiliser un constructeur, l'autre option consiste à utiliser la méthode inject. Le constructeur peut ressembler à ceci :
@Component({ … })
class HeroListComponent {
constructor(private service: HeroService) {}
}
utiliser la méthode d'injection :
@Component({ … })
class HeroListComponent {
private service = inject(HeroService);
}
(类似于spring 三级缓存管理bean 的机制)Lorsqu'Angular découvre qu'un composant dépend d'un service, il vérifie d'abord si l'injecteur a une instance existante de ce service. Si une instance de service demandée ne se termine pas encore, l'injecteur en crée un en utilisant le fournisseur enregistré et l'ajoute à l'injecteur avant de renvoyer le service à Angular.
Lorsque tous les services demandés ont été résolus et renvoyés, Angular peut appeler le constructeur du composant avec ces services comme arguments.
5. Cas
Ceci est mon composant bonjour, je souhaite faire référence à un autre composant : anglais
import {Component} from "@angular/core";
@Component({"template":"<div>I love studying</div>"})
export class StudyEnglishComponent{
public vocabulary(){
console.log("for the record, I have finished my vocabulary today!")
}
}
import 'reflect-metadata'
import { Component } from "@angular/core";
import { StudyEnglishComponent} from "../study/study.english.component";
// @MyComponent({
// "selector":'hello-word',
// "template":'<div>hello word</div>',
// })
@Component({'selector':'hello-word',template:'<div class="hello" style="font:200px">hello world</div>',styleUrls:['./helloWord.component.css']})
export class HelloComponent{
public studyEnglish:StudyEnglishComponent;
constructor(english:StudyEnglishComponent){
this.studyEnglish=english;
this.sayHai(this.say);
}
public say="hi angular !";
public sayHai(params:String) {
this.studyEnglish.vocabulary();
return "hi,"+params;
}
}
mais j'obtiens une erreur comme celle-ci : NullInjectorError : R3InjectorError(AppModule)[StudyEnglishComponent -> StudyEnglishComponent -> StudyEnglishComponent] :
NullInjectorError : No supplier for StudyEnglishComponent !
Comment résoudre ce problème ?
1. ajoutez le décorateur @Injectable sur StudyEnglishComponent pour déclarer que cette classe est un fournisseur.
import {Component,Injectable} from "@angular/core";
@Component({"template":"<div>I love studying</div>"})
@Injectable()
export class StudyEnglishComponent{
public vocabulary(){
console.log("for the record, I have finished my vocabulary today!")
}
}
2. Utilisez le constructeur pour injecter le StudyEnglishComponent
import { Component } from "@angular/core";
import { StudyEnglishComponent} from "../study/study.english.component";
@Component({
selector:'hello-word',
template:'<div class="hello" style="font:200px">hello world</div>',
styleUrls:['./helloWord.component.css'],
providers:[StudyEnglishComponent]
})
export class HelloComponent{
public say="hi angular !";
public studyEnglish:StudyEnglishComponent;
/**
* 使用构造器形式注入
*/
constructor(studyEnglish:StudyEnglishComponent){
this.studyEnglish=studyEnglish;
console.log(this.sayHai(this.say));
}
public sayHai(params:String) {
this.studyEnglish.vocabulary();
return "hi,"+params;
}
}
redémarrez votre service et voyez la console :
Problème résolu !