Angular fournit un crochet de cycle de vie ngOnInit
par défaut.
Pourquoi devrait-on utiliser ngOnInit
, si nous avons déjà un constructor
?
Constructor
est une méthode par défaut de la classe qui est exécutée lors de l'instanciation de la classe et garantit l'initialisation correcte des champs de la classe et de ses sous-classes. Angular or Better Dependency Injector (DI) analyse les paramètres du constructeur et lorsqu'il crée une nouvelle instance en appelant new MyClass()
, il essaie de trouver des fournisseurs correspondant aux types des paramètres du constructeur, les résout et les transmet au constructeur de la manière suivante:
new MyClass(someArg);
ngOnInit
est un crochet de cycle de vie appelé par Angular2 pour indiquer que Angular est terminé lors de la création du composant.
Nous devons importer OnInit
pour pouvoir utiliser ceci (en réalité, implémenter OnInit
n'est pas obligatoire, mais est considéré comme une bonne pratique):
import {Component, OnInit} from '@angular/core';
ensuite, pour utiliser la méthode de OnInit
, nous devons implémenter dans la classe comme ceci.
export class App implements OnInit{
constructor(){
//called first time before the ngOnInit()
}
ngOnInit(){
//called after the constructor and called after the first ngOnChanges()
}
}
Implémentez cette interface pour exécuter une logique d'initialisation personnalisée après que les propriétés liées aux données de votre directive aient été initialisées . ngOnInit est appelée juste après que les propriétés liées à la directive de la directive ont été vérifiées pour la première fois, et avant qu'aucun de ses enfants n'ait été vérifié. Elle n'est invoquée qu'une seule fois lorsque la directive est instanciée.
La plupart du temps, nous utilisons ngOnInit
pour toutes les initialisations/déclarations et nous évitons que des éléments ne fonctionnent dans le constructeur. Le constructeur ne doit être utilisé que pour initialiser les membres de la classe mais ne doit pas effectuer de "travail" réel.
Donc, vous devriez utiliser constructor()
pour configurer l’injection de dépendance et pas grand-chose d’autre. ngOnInit () est le meilleur endroit pour "commencer" - c'est où/quand les liaisons des composants sont résolues.
Pour plus d'informations, voir ici:
L'article La différence essentielle entre Constructor et ngOnInit in Angular explore la différence sous de multiples perspectives. Cette réponse fournit l'explication de différence la plus importante liée au processus d'initialisation de composant, qui montre également l'utilisation différente.
Le processus de bootstrap angulaire comprend les deux étapes principales:
Le constructeur du composant est appelé lorsque l'arborescence des composants de constructions angulaires. Tous les hooks de cycle de vie sont appelés dans le cadre de la détection des modifications.
Lorsque l'arborescence des composants de constructions angulaires est configurée, l'injecteur de module racine est déjà configuré afin que vous puissiez injecter toutes les dépendances globales. De même, lorsque Angular instancie une classe de composant enfant, l'injecteur du composant parent est également déjà configuré afin que vous puissiez injecter les fournisseurs définis sur le composant parent, y compris le composant parent lui-même. Les constructeurs de composants est la seule méthode appelée dans le contexte de l'injecteur, donc si vous avez besoin d'une dépendance, c'est le seul endroit où obtenir ces dépendances.
Lorsque Angular commence à détecter les modifications, l’arborescence des composants est construite et les constructeurs de tous les composants de l’arborescence ont été appelés. De plus, chaque nœud de modèle de composant est ajouté au DOM. Le mécanisme de communication @Input
est traité lors de la détection des modifications. Vous ne pouvez donc pas vous attendre à ce que les propriétés soient disponibles dans le constructeur. Il sera disponible après ngOnInit
.
Voyons un exemple rapide. Supposons que vous ayez le modèle suivant:
<my-app>
<child-comp [i]='prop'>
Donc Angular commence à démarrer l’application. Comme je l'ai dit, il crée d'abord des classes pour chaque composant. Il appelle donc le constructeur MyAppComponent
. Il crée également un nœud DOM qui est l'élément hôte du composant my-app
. Ensuite, il crée un élément Host pour le child-comp
et appelle le constructeur ChildComponent
. À ce stade, la liaison d'entrée i
et les hooks de cycle de vie ne sont pas vraiment concernés. Ainsi, lorsque ce processus est terminé, Angular se termine par l'arborescence suivante de vues de composants:
MyAppView
- MyApp component instance
- my-app Host element data
ChildCompnentView
- ChildComponent component instance
- child-comp Host element data
Ce n’est qu’à ce moment-là qu’il exécute la détection des modifications et met à jour les liaisons pour my-app
et appelle ngOnInit
sur la classe MyAppComponent. Ensuite, il met à jour les liaisons pour le child-comp
et appelle ngOnInit
sur la classe ChildComponent.
Vous pouvez effectuer votre logique d’initialisation dans le constructeur ou dans ngOnInit
en fonction des besoins. Par exemple, l'article Voici comment obtenir ViewContainerRef avant que la requête @ViewChild soit évaluée indique le type de logique d'initialisation qui doit être effectuée dans le constructeur.
Voici quelques articles qui vous aideront à mieux comprendre le sujet:
Je pense que le meilleur exemple consisterait à utiliser des services. Supposons que je souhaite récupérer les données de mon serveur lorsque mon composant est activé. Supposons que je souhaite également ajouter des éléments supplémentaires aux données après les avoir reçues du serveur. Peut-être que je reçois une erreur et que je souhaite le consigner différemment.
C'est vraiment facile avec ngOnInit sur un constructeur, cela limite également le nombre de couches de rappel que je dois ajouter à mon application.
Par exemple:
export class Users implements OnInit{
user_list: Array<any>;
constructor(private _userService: UserService){
};
ngOnInit(){
this.getUsers();
};
getUsers(){
this._userService.getUsersFromService().subscribe(users => this.user_list = users);
};
}
avec mon constructeur, je pourrais simplement appeler mon _userService et remplir ma liste d'utilisateurs, mais peut-être que je veux faire des choses supplémentaires avec elle. Par exemple, assurez-vous que tout est en ordre de grandeur, je ne suis pas tout à fait sûr de la manière dont mes données sont transmises.
Cela facilite donc beaucoup l'utilisation de ngOnInit.
export class Users implements OnInit{
user_list: Array<any>;
constructor(private _userService: UserService){
};
ngOnInit(){
this.getUsers();
};
getUsers(){
this._userService.getUsersFromService().subscribe(users => this.user_list = users);
this.user_list.toUpperCase();
};
}
Il est beaucoup plus facile de voir, et j'appelle donc ma fonction dans mon composant lorsque je l'initialise au lieu d'avoir à le creuser ailleurs. Vraiment, ce n'est qu'un autre outil que vous pouvez utiliser pour faciliter la lecture et l'utilisation future. De plus, je trouve que c'est vraiment une mauvaise pratique de mettre des appels de fonction dans un constructeur!
OK, tout d'abord ngOnInit
fait partie de cycle de vie angulaire, alors que constructor
fait partie de ES6 classe JavaScript, la différence principale commence donc ici! ...
Regardez le tableau ci-dessous que j'ai créé et qui montre le cycle de vie de Angular.
Dans Angular2 +, nous utilisons constructor
pour faire la DI(Dependency Injection)
pour nous, tandis que dans Angular 1, cela se produisait en appelant la méthode String et en vérifiant quelle dépendance était injectée.
Comme vous le voyez dans le diagramme ci-dessus, ngOnInit
se produit une fois que le constructeur est prêt et ngOnChnages
et est activé une fois que le composant est prêt pour nous. Toutes les initialisations peuvent se produire à ce stade, un simple échantillon injecte un service et l'initialise sur init.
OK, je partage également un exemple de code que vous pouvez consulter. Découvrez comment nous utilisons les variables ngOnInit
et constructor
dans le code ci-dessous:
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'my-app',
template: `<h1>App is running!</h1>
<my-app-main [data]=data></<my-app-main>`,
styles: ['h1 { font-weight: normal; }']
})
class ExampleComponent implements OnInit {
constructor(private router: Router) {} //Dependency injection in the constructor
// ngOnInit, get called after Component initialised!
ngOnInit() {
console.log('Component initialised!');
}
}
Le premier (constructeur) est lié à l'instanciation de classe et n'a rien à voir avec Angular2. Je veux dire qu'un constructeur peut être utilisé sur n'importe quelle classe. Vous pouvez y mettre un certain traitement d'initialisation pour l'instance nouvellement créée.
Le second correspond à un hook de cycle de vie de composants Angular2:
Extrait du site officiel d'angular:
ngOnChanges
est appelé quand une valeur de liaison d'entrée ou de sortie changengOnInit
est appelé après la premièrengOnChanges
Donc vous devriez utiliser ngOnInit
si le traitement d'initialisation repose sur des liaisons du composant (par exemple, les paramètres de composant définis avec @Input
), sinon le constructeur suffirait ...
_ {Une réponse courte et simple serait,} _
Constructor
: constructor
est un default method
exécuté (par défaut) lors de la construction du composant. Lorsque vous créez an instance
d'une classe, cette heure est également appelée constructor(default method)
. Donc, en d'autres termes, lorsque le composant est en train d'être appelé, constructed or/and an instance is created constructor(default method)
est appelé et le code pertinent écrit à l'intérieur est appelé. Fondamentalement et généralement dans Angular2
, il utilisait des éléments tels que services
lors de la construction du composant pour une utilisation ultérieure.
OnInit
: ngOnInit est le hook de cycle de vie du composant qui s'exécute en premier après constructor(default method)
lorsque le composant est en cours d'initialisation.
Donc, votre constructeur sera appelé en premier et Oninit sera appelé plus tard après la méthode du constructeur.
boot.ts
import {Cmomponent, OnInit} from 'angular2/core';
import {ExternalService} from '../externalService';
export class app implements OnInit{
constructor(myService:ExternalService)
{
this.myService=myService;
}
ngOnInit(){
// this.myService.someMethod()
}
}
Ressources: Crochet LifeCycle
Vous pouvez vérifier cette petite démo qui montre la mise en œuvre des deux choses.
Je vais juste ajouter une chose importante qui a été sautée dans les explications ci-dessus et explique quand vous DEVEZ utiliser ngOnInit
.
Si vous manipulez le DOM du composant via, par exemple, ViewChildren, ContentChildren ou ElementRef, vos éléments natifs ne seront pas disponibles pendant la phase du constructeur.
Cependant, étant donné que ngOnInit
se produit une fois le composant créé et les vérifications (ngOnChanges
) appelées, vous pouvez accéder au DOM à ce stade.
export class App implements OnInit, AfterViewInit, AfterContentInit {
@Input() myInput: string;
@ViewChild() myTemplate: TemplateRef<any>;
@ContentChild(ChildComponent) myComponent: ChildComponent;
constructor(private elementRef: ElementRef) {
// this.elementRef.nativeElement is undefined here
// this.myInput is undefined here
// this.myTemplate is undefined here
// this.myComponent is undefine here
}
ngOnInit() {
// this.elementRef.nativeElement can be used from here on
// value of this.myInput is passed from parent scope
// this.myTemplate and this.myComponent are still undefined
}
ngAfterContentInit() {
// this.myComponent now gets projected in and can be accessed
// this.myTemplate is still undefined
}
ngAfterViewInit() {
// this.myTemplate can be used now as well
}
}
Pour tester cela, j’ai écrit ce code en empruntant au Tutoriel NativeScript :
user.ts
export class User {
email: string;
password: string;
lastLogin: Date;
constructor(msg:string) {
this.email = "";
this.password = "";
this.lastLogin = new Date();
console.log("*** User class constructor " + msg + " ***");
}
Login() {
}
}
login.component.ts
import {Component} from "@angular/core";
import {User} from "./../../shared/user/user"
@Component({
selector: "login-component",
templateUrl: "pages/login/login.html",
styleUrls: ["pages/login/login-common.css", "pages/login/login.css"]
})
export class LoginComponent {
user: User = new User("property"); // ONE
isLoggingIn:boolean;
constructor() {
this.user = new User("constructor"); // TWO
console.log("*** Login Component Constructor ***");
}
ngOnInit() {
this.user = new User("ngOnInit"); // THREE
this.user.Login();
this.isLoggingIn = true;
console.log("*** Login Component ngOnInit ***");
}
submit() {
alert("You’re using: " + this.user.email + " " + this.user.lastLogin);
}
toggleDisplay() {
this.isLoggingIn = !this.isLoggingIn;
}
}
Sortie de la console
JS: *** User class constructor property ***
JS: *** User class constructor constructor ***
JS: *** Login Component Constructor ***
JS: *** User class constructor ngOnInit ***
JS: *** Login Component ngOnInit ***
La principale différence entre constructor et ngOnInit
est que ngOnInit
est cycle de vie et s'exécute après le constructeur. Le modèle interpolé par composant et les valeurs initiales en entrée ne sont pas disponibles dans le constructeur, mais ils sont disponibles dans ngOnInit
.
La différence pratique réside dans la manière dont ngOnInit
affecte la structure du code. La plupart des codes d'initialisation peuvent être déplacés vers ngOnInit
- tant que cela ne crée pas de conditions de concurrence.
Une quantité importante de code d'initialisation rend la méthode constructeur difficile à étendre, à lire et à tester.
Une recette habituelle pour séparer la logique d'initialisation du constructeur de classe consiste à le déplacer vers une autre méthode telle que init
:
class Some {
constructor() {
this.init();
}
init() {...}
}
ngOnInit
peut servir cet objectif dans les composants et les directives:
constructor(
public foo: Foo,
/* verbose list of dependencies */
) {
// time-sensitive initialization code
this.bar = foo.getBar();
}
ngOnInit() {
// rest of initialization code
}
Le rôle principal des constructeurs de classe dans Angular est l’injection de dépendance. Les constructeurs sont également utilisés pour l'annotation DI dans TypeScript. Presque toutes les dépendances sont attribuées en tant que propriétés à une instance de classe.
Le constructeur moyen de composant/directive est déjà assez grand car il peut avoir une signature multiligne en raison de dépendances, ce qui place la logique d'initialisation inutile dans le corps du constructeur contribue à l'antipattern.
Le constructeur d'initialisation asynchrone peut souvent être considéré comme un antipattern et avoir une odeur, car l'instanciation de classe se termine avant la routine asynchrone, ce qui peut créer des conditions de concurrence. Si ce n’est pas le cas, ngOnInit
et d’autres hooks de cycle de vie sont de meilleurs endroits pour cela, en particulier parce qu’ils peuvent tirer parti de la syntaxe async
:
constructor(
public foo: Foo,
public errorHandler: ErrorHandler
) {}
async ngOnInit() {
try {
await this.foo.getBar();
await this.foo.getBazThatDependsOnBar();
} catch (err) {
this.errorHandler.handleError(err);
}
}
S'il existe des conditions de concurrence (y compris celle selon laquelle un composant ne doit pas apparaître en cas d'erreur d'initialisation), une routine d'initialisation asynchrone doit avoir lieu avant l'instanciation du composant et être déplacée vers le composant parent, la protection du routeur, etc.
ngOnInit
est plus flexible qu'un constructeur et offre certains avantages pour les tests unitaires qui sont expliqués en détail dans cette réponse .
Etant donné que ngOnInit
n'est pas appelée automatiquement lors de la compilation de composants dans les tests unitaires, les méthodes appelées dans ngOnInit
peuvent être espionnées ou simulées après l'instanciation de composant.
Dans des cas exceptionnels, ngOnInit
peut être entièrement stubé pour isoler d'autres unités de composant (par exemple, une logique de modèle).
Les classes enfants peuvent uniquement augmenter les constructeurs, pas les remplacer.
Etant donné que this
ne peut pas être référencé avant super()
, ceci impose des restrictions à la priorité d'initialisation.
Considérant que le composant ou la directive angulaire utilise ngOnInit
pour une logique d'initialisation ne prenant pas le temps en compte, les classes enfant peuvent choisir si super.ngOnInit()
est appelé et à quel moment:
ngOnInit() {
this.someMethod();
super.ngOnInit();
}
Ce serait impossible à mettre en œuvre avec le seul constructeur.
Comme beaucoup d'autres langages, vous pouvez initialiser des variables au niveau de la classe, du constructeur ou d'une méthode. Il appartient au développeur de décider de ce qui convient le mieux dans son cas particulier. Vous trouverez ci-dessous une liste des meilleures pratiques en matière de décision.
Habituellement, vous déclarerez ici toutes vos variables qui seront utilisées dans le reste de votre composant. Vous pouvez les initialiser si la valeur ne dépend d’aucun autre élément ou utiliser le mot-clé const pour créer des constantes si elles ne changent pas.
export class TestClass{
let varA: string = "hello";
}
Il est généralement recommandé de ne rien faire dans le constructeur et de l’utiliser uniquement pour les classes qui seront injectées. La plupart du temps, votre constructeur devrait ressembler à ceci:
constructor(private http: Http, private customService: CustomService) {}
cela créera automatiquement les variables de niveau classe, de sorte que vous aurez accès à customService.myMethod()
sans avoir à le faire manuellement.
NgOnit est un crochet de cycle de vie fourni par le framework Angular 2. Votre composant doit implémenter OnInit
pour pouvoir l'utiliser. Ce hook de cycle de vie est appelé après l'appel du constructeur et toutes les variables sont initialisées. Le gros de votre initialisation devrait aller ici. Vous aurez la certitude qu'Angular a correctement initialisé votre composant et vous pouvez commencer à exécuter toute la logique dont vous avez besoin dans OnInit
plutôt que de procéder de la sorte lorsque le chargement de votre composant n'est pas terminé correctement.
Voici une image détaillant l'ordre de ce qui s'appelle:
https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html
Si vous utilisez le framework Angular 2 et souhaitez interagir avec certains événements du cycle de vie, utilisez les méthodes fournies par le framework pour éviter les problèmes.
Les réponses ci-dessus ne répondent pas vraiment à cet aspect de la question initiale: Qu'est-ce qu'un crochet de cycle de vie? Il m'a fallu un certain temps pour comprendre ce que cela voulait dire jusqu'à ce que j'y pense de cette façon.
1) Supposons que votre composant est un humain. Les humains ont des vies qui comprennent de nombreuses étapes de la vie, puis nous expirons.
2) Notre composante humaine pourrait avoir le scénario de cycle de vie suivant: Naissance, bébé, primaire, jeune adulte, adulte d'âge moyen, aîné, mort, éliminé.
3) Dites que vous voulez avoir une fonction pour créer des enfants. Pour éviter que cela ne devienne compliqué et plutôt humoristique, vous voulez que votre fonction ne soit appelée que pendant le stade Jeune adulte de la vie humaine. Vous développez donc un composant qui n’est actif que lorsque le composant parent est au stade Jeune adulte. Les crochets vous aident à faire cela en signalant cette étape de la vie et en laissant votre composant agir dessus.
Truc amusant. Si vous laissez votre imagination aller à coder quelque chose comme cela, cela devient compliqué et amusant.
Leconstructeurest une méthode en JavaScript et est considéré comme une fonctionnalité de la classe dans es6. Lorsque la classe est instanciée, elle exécute immédiatement le constructeur, qu'elle soit utilisée dans un framework angulaire ou non. appelé par le moteur JavaScript et Angular n’a aucun contrôle sur cela.
import {Component} from '@angular/core';
@Component({})
class CONSTRUCTORTEST {
//This is called by Javascript not the Angular.
constructor(){
console.log("view constructor initialised");
}
}
La classe "ConstructorTest" est instanciée ci-dessous; elle appelle donc en interne le constructeur (Tout cela se fait par JavaScript (es6) no Angular).
new CONSTRUCTORTEST();
C'est pourquoi il y angOnInitlifecycle hook dans Angular.ngOnInit rendu lorsque Angular a fini d'initialiser le composant.
import {Component} from '@angular/core';
@Component({})
class NGONINITTEST implements onInit{
constructor(){}
//ngOnInit calls by Angular
ngOnInit(){
console.log("Testing ngOnInit");
}
}
Premièrement, nous instancions la classe comme ci-dessous qui arrive aux exécutions immédiates de la méthode constructeur.
let instance = new NGONINITTEST();
ngOnInit est appelé par Angular si nécessaire comme ci-dessous:
instance.ngOnInit();
Mais vous pouvez demander pourquoi nous utilisons constructeur dans Angular?
La réponse estdépendances injectionsComme mentionné précédemment, le constructeur appelle par le moteur JavaScript immédiatement lorsque la classe est instanciée (avant d'appeler ngOnInit par Angular). sont définis dans le constructeur et indique finalement à Angular quel type de dépendances nous souhaitons utiliser dans ce composant spécifique.
Deux choses à observer ici:
Les deux ont une convivialité différente.
Constructeur: La méthode du constructeur d'une classe ES6 (ou TypeScript dans ce cas) est une fonctionnalité d'une classe elle-même, plutôt qu'une fonctionnalité angulaire. C’est hors du contrôle de Angular lorsque le constructeur est appelé, ce qui signifie que ce n’est pas un crochet approprié pour vous avertir lorsque Angular a fini d’initialiser le composant. Le moteur JavaScript appelle le constructeur et non directement Angular. C'est pourquoi le hook de cycle de vie ngOnInit (et $ onInit dans AngularJS) a été créé. Gardant cela à l'esprit, il existe un scénario approprié pour utiliser le constructeur. C’est à ce moment-là que nous voulons utiliser l’injection de dépendance, essentiellement pour «intégrer» les dépendances dans le composant.
Lorsque le constructeur est initialisé par le moteur JavaScript, TypeScript nous permet d'indiquer à Angular les dépendances à mapper avec une propriété spécifique.
ngOnInit est purement là pour nous indiquer que Angular a fini d’initialiser le composant.
Cette phase inclut le premier passage de Détection de changement par rapport aux propriétés que nous pouvons lier au composant lui-même, comme l’utilisation d’un décorateur @Input ().
De ce fait, les propriétés @Input () sont disponibles dans ngOnInit, mais ne sont pas définies dans le constructeur, de par leur conception.
Les deux méthodes ont des objectifs/responsabilités différents. La tâche du constructeur (qui est une fonctionnalité prise en charge par le langage) est de s’assurer que l’invariant de représentation tient. Autrement, vous devez vous assurer que l'instance est valide en donnant les valeurs correctes aux membres. Il appartient au développeur de décider de ce que «correct» signifie.
La tâche de la méthode onInit () (qui est un concept angulaire) est de permettre les invocations de méthode sur un objet correct (invariant de représentation). Chaque méthode doit à son tour s'assurer que l'invariant de représentation est maintenu lorsque la méthode se termine.
Le constructeur doit être utilisé pour créer des objets 'corrects', la méthode onInit vous donne la possibilité d'appeler des appels de méthode à une instance bien définie.
constructeur () est la méthode par défaut du cycle de vie du composant et est utilisée pour l'injection de dépendance. Le constructeur est une fonctionnalité TypeScript.
ngOnInit () est appelé après le constructeur et ngOnInit est appelé après les premiers ngOnChanges.
i.e. Constructor () -> ngOnChanges () -> ngOnInit ()
comme mentionné ci-dessus, ngOnChanges () est appelé lorsqu'une valeur de liaison d'entrée ou de sortie change.
Constructor est le premier, et cela se produit parfois lorsque @input data a la valeur null!
constructor(translate: TranslateService, private oauthService: OAuthService) {
translate.setDefaultLang('En');
translate.use('En');}
Exemple pour onInit:
ngOnInit() {
this.items = [
{ label: 'A', icon: 'fa fa-home', routerLink: ['/'] },
{ label: 'B', icon: 'fa fa-home', routerLink: ['/'] }]
}
Je pense que onInit est comme InitialComponents () dans WinForm.
J'ai trouvé la réponse et j'ai essayé de la traduire en anglais: Cette question se posait encore, même lors d'entretiens techniques. En fait, il y a une grande ressemblance entre les deux, mais il y a aussi des différences.
Le constructeur fait partie de ECMAScript. D'autre part, ngOnInit () est une notion d'angulaire.
Nous pouvons appeler les constructeurs dans toutes les classes même si nous n'utilisons pas Angular
LifeCycle: le constructeur est appelé avant ngOnInt ()
Dans le constructeur, nous ne pouvons pas appeler des éléments HTML. Cependant, dans ngOnInit (), nous pouvons le faire.
Généralement, les appels de services dans ngOnInit () et non dans le constructeur
En fait, ngOnInit () pour deux raisons principales:
1) Effectuer des initialisations complexes peu de temps après la construction.
2) Pour configurer le composant après Angular, définissez les propriétés d'entrée.
Les développeurs expérimentés conviennent que les composants devraient être peu coûteux et sûrs à construire.
Misko Hevery, Angular chef d'équipe, explique pourquoi vous devez éviter la logique de constructeur complexe.
Ne récupérez pas de données dans un constructeur de composant. Vous ne devriez pas vous inquiéter du fait qu'un nouveau composant essaiera de contacter un serveur distant lors de sa création sous test ou avant que vous ne décidiez de l'afficher. Les constructeurs ne devraient pas faire plus que définir les variables locales initiales à des valeurs simples.
Un ngOnInit () est un bon endroit pour qu'un composant récupère ses données initiales.
N'oubliez pas non plus que les propriétés d'entrée liées aux données d'une directive ne sont définies qu'après la construction. C'est un problème si vous devez initialiser la directive en fonction de ces propriétés. Ils auront été définis lorsque ngOnInit () sera exécuté.
La méthode ngOnChanges () est votre première opportunité d'accéder à ces propriétés. Angular appelle ngOnChanges () avant ngOnInit () et plusieurs fois par la suite. Il appelle seulement ngOnInit () une fois.
Vous pouvez compter sur Angular pour appeler la méthode ngOnInit () peu de temps après la création du composant. C’est là que la logique d’initialisation lourde appartient.
Constructeur Un constructeur de classe dans Angular est principalement utilisé pour injecter des dépendances. Angular appelle ce schéma d'injection du constructeur, expliqué en détail ici. Pour une analyse architecturale plus approfondie, vous pouvez lire Constructor Injection vs. Setter Injection de Miško Hevery.
Cependant, l'utilisation d'un constructeur n'est pas limitée à DI. Par exemple, la directive routeur-prise de @ angular/module de routeur l'utilise pour s'enregistrer et pour localiser son emplacement (viewContainerRef) dans l'écosystème du routeur. J'ai décrit cette approche dans Voici comment obtenir ViewContainerRef avant que la requête @ViewChild soit évaluée.
Pourtant, la pratique courante met le moins de logique possible dans le constructeur.
NgOnInit Comme nous l'avons appris plus haut lorsque Angular appelle ngOnInit, la création d'un composant DOM est terminée. Elle a injecté toutes les dépendances requises via le constructeur et les liaisons d'entrée traitées. Vous disposez donc de toutes les informations requises, ce qui en fait un bon endroit pour exécuter la logique d’initialisation.
Il est courant d’utiliser ngOnInit pour exécuter la logique d’initialisation même si cette logique ne dépend pas de DI, de DOM ou de liaisons d’entrée.
Dans les cycles de vie angulaires
1) L'injecteur angulaire détecte le paramètre constructeur ('s) et instancie la classe.
2) Cycle de vie du prochain appel angulaire
Crochets angulaires de cycle de vie
ngOnChanges -> Liaison des paramètres de la directive d’appel.
ngOnInit -> Démarrer le rendu angulaire ...
Appelez une autre méthode avec l'état du cycle de vie angulaire.
La variable constructor
est appelée lorsque Angular "instancie/construit" le composant . La méthode ngOnInit
est un crochet qui représente la partie d'initialisation du cycle de vie du composant . Une bonne pratique consiste à ne l'utiliser que pour service injection :
constructor(private
service1: Service1,
service2: Service2
){};
Même si cela est possible, vous ne devriez pas effectuer de "travail" à l'intérieur de . Si vous souhaitez lancer une action devant se produire lors de "l'initialisation" du composant, utilisez ngOnInit
:
ngOnInit(){
service1.someWork();
};
De plus, les actions impliquant les propriétés d'entrée , provenant d'un composant parent, ne peuvent pas être effectuées dans le constructeur . Elles doivent être placées dans la méthode ngOnInit
ou un autre crochet . Il en est de même pour l'élément liés à la vue (le DOM), par exemple, éléments viewchild :
@Input itemFromParent: string;
@ViewChild('childView') childView;
constructor(){
console.log(itemFromParent); // KO
// childView is undefined here
};
ngOnInit(){
console.log(itemFromParent); // OK
// childView is undefined here, you can manipulate here
};
Constructeur est une fonction exécutée lors de la construction du composant (ou d'une autre classe).
ngOnInit est une fonction appartenant à un groupe de méthodes de cycle de vie du composant et elles sont exécutées à un moment différent de notre composant (c'est pourquoi le nom du cycle de vie) . Voici une liste de tous:
Le constructeur sera exécuté avant toute fonction de cycle de vie.
constructor()
est utilisé pour effectuer une injection de dépendance.
ngOnInit()
, ngOnChanges()
et ngOnDestroy()
etc. sont des méthodes de cycle de vie. ngOnChanges()
sera le premier à être appelé, avant ngOnInit()
, lorsque la valeur d'une propriété liée change, elle ne sera PAS appelée s'il n'y a pas de changement. ngOnDestroy()
est appelé lorsque le composant est supprimé. Pour l'utiliser, OnDestroy
doit être implement
ed par la classe.