Differenza tra Constructor e ngOnInit

Angular fornisce il ciclo di vita hook ngOnInit di default.

Perché dovrebbe essere usato ngOnInit , se abbiamo già un constructor ?

Il Constructor è un metodo predefinito della class che viene eseguito quando la class viene istanziata e garantisce l’inizializzazione corretta dei campi nella class e nelle sue sottoclassi. L’iniettore di dipendenza angular o migliore (DI) analizza i parametri del costruttore e quando crea una nuova istanza chiamando new MyClass() cerca di trovare provider che corrispondono ai tipi dei parametri del costruttore, li risolve e li passa al costruttore come

 new MyClass(someArg); 

ngOnInit è un hook del ciclo di vita chiamato da Angular2 per indicare che Angular ha finito di creare il componente.

Dobbiamo importare OnInit per poter usare in questo modo (l’implementazione di OnInit non è obbligatoria ma considerata una buona pratica):

 import {Component, OnInit} from '@angular/core'; 

quindi per utilizzare il metodo di OnInit dobbiamo implementare nella class come questa.

 export class App implements OnInit{ constructor(){ //called first time before the ngOnInit() } ngOnInit(){ //called after the constructor and called after the first ngOnChanges() } } 

Implementare questa interfaccia per eseguire la logica di inizializzazione personalizzata dopo l’inizializzazione delle proprietà associate ai dati della direttiva. ngOnInit viene chiamato subito dopo che le proprietà legate ai dati della direttiva sono state controllate per la prima volta e prima che uno dei suoi figli sia stato controllato. Viene richiamato una sola volta quando viene istanziata la direttiva.

Principalmente usiamo ngOnInit per tutte le inizializzazioni / dichiarazioni ed evitiamo di lavorare nel costruttore. Il costruttore dovrebbe essere usato solo per inizializzare i membri della class, ma non dovrebbe fare “lavoro” effettivo.

Quindi dovresti usare constructor() per configurare Dependency Injection e non molto altro. ngOnInit () è il posto migliore per “iniziare” – è dove / quando i collegamenti dei componenti sono stati risolti.

Per maggiori informazioni consultare qui:

Penso che l’esempio migliore sarebbe utilizzare i servizi. Diciamo che voglio prendere i dati dal mio server quando il mio componente viene “Attivato”. Diciamo che voglio anche aggiungere qualcosa ai dati dopo averlo ricevuto dal server, forse ho un errore e voglio registrarlo in modo diverso.

È davvero facile con ngOnInit su un costruttore, ma limita anche quanti livelli di callback devo aggiungere alla mia applicazione.

Per esempio:

 export class Users implements OnInit{ user_list: Array; constructor(private _userService: UserService){ }; ngOnInit(){ this.getUsers(); }; getUsers(){ this._userService.getUsersFromService().subscribe(users => this.user_list = users); }; } 

con il mio costruttore potrei semplicemente chiamare il mio _userService e popolare la mia user_list, ma forse voglio fare qualcosa in più con esso. Come per assicurarmi che tutto sia upper_case, non sono del tutto sicuro di come stanno arrivando i miei dati.

Quindi rende molto più facile l’uso di ngOnInit.

 export class Users implements OnInit{ user_list: Array; constructor(private _userService: UserService){ }; ngOnInit(){ this.getUsers(); }; getUsers(){ this._userService.getUsersFromService().subscribe(users => this.user_list = users); this.user_list.toUpperCase(); }; } 

Rende molto più facile vedere, e così chiamo la mia funzione all’interno del mio componente durante l’inizializzazione invece di dover scavare per qualche altra parte. In realtà è solo un altro strumento che puoi usare per renderlo più facile da leggere e utilizzare in futuro. Inoltre trovo davvero una ctriggers pratica mettere le chiamate di funzione all’interno di un costruttore!

L’articolo La differenza essenziale tra Constructor e ngOnInit in Angular esplora la differenza da più punti di vista. Questa risposta fornisce la spiegazione della differenza più importante relativa al processo di inizializzazione del componente che mostra anche le diverse modalità di utilizzo.

Il processo di avvio angular consiste delle due fasi principali:

  • costruzione di componenti albero
  • rilevamento del cambio di marcia

Il costruttore del componente viene chiamato quando Angular costruisce l’albero dei componenti. Tutti i hook del ciclo di vita vengono chiamati come parte del rilevamento delle modifiche in esecuzione.

Quando Angular costruisce i componenti tree l’injector del modulo root è già configurato in modo da poter inserire eventuali dipendenze globali. Inoltre, quando Angular crea un’istanza di una class di componenti figlio, l’iniettore per il componente principale è già impostato in modo tale da poter iniettare i provider definiti sul componente principale, incluso il componente principale stesso. Costruttori di componenti è l’unico metodo che viene chiamato nel contesto dell’iniettore, quindi se hai bisogno di una dipendenza è l’unico posto in cui ottenere tali dipendenze.

Quando Angular inizia a rilevare il rilevamento, l’albero dei componenti viene costruito e sono stati chiamati i costruttori per tutti i componenti dell’albero. Anche i nodes dei modelli di ogni componente vengono aggiunti al DOM. Il meccanismo di comunicazione @Input viene elaborato durante il rilevamento delle modifiche, quindi non ci si può aspettare che le proprietà siano disponibili nel costruttore. Sarà disponibile dopo ngOnInit .

Vediamo un rapido esempio. Supponiamo di avere il seguente modello:

   

Quindi Angular avvia il bootstrap dell’applicazione. Come ho detto prima crea classi per ogni componente. Quindi chiama il costruttore MyAppComponent . Crea anche un nodo DOM che è l’elemento host del componente my-app . Quindi procede alla creazione di un elemento host per il child-comp e chiamando il costruttore ChildComponent . A questo punto non si tratta veramente del binding dell’input i e di eventuali hook del ciclo di vita. Quindi, quando questo processo è finito, Angular termina con il seguente albero di viste componente:

 MyAppView - MyApp component instance - my-app host element data ChildCompnentView - ChildComponent component instance - child-comp host element data 

Solo in seguito esegue il rilevamento delle modifiche e aggiorna i collegamenti per la my-app e chiama ngOnInit sulla class MyAppComponent. Quindi procede all’aggiornamento dei binding per il child-comp e chiama ngOnInit sulla class ChildComponent.

È ansible eseguire la logica di inizializzazione in qualsiasi costruttore o ngOnInit base a ciò che è necessario disponibile. Ad esempio l’articolo Ecco come ottenere ViewContainerRef prima che la query @ViewChild sia valutata mostra quale tipo di logica di inizializzazione può essere richiesta per essere eseguita nel costruttore.

Ecco alcuni articoli che ti aiuteranno a capire meglio l’argomento:

  • Tutto ciò che devi sapere sul rilevamento dei cambiamenti in Angular
  • Il digest di Angular è rinato nella nuova versione di Angular
  • Aggiornamento della meccanica dei binding di proprietà in Angular

Il primo (costruttore) è correlato all’istanza della class e non ha nulla a che fare con Angular2. Voglio dire che un costruttore può essere utilizzato su qualsiasi class. Puoi inserire qualche elaborazione di inizializzazione per l’istanza appena creata.

Il secondo corrisponde ad un hook del ciclo di vita dei componenti Angular2:

Citato dal sito web ufficiale di angular:

  • ngOnChanges viene chiamato quando un valore di binding di input o output cambia
  • ngOnInit viene chiamato dopo i primi ngOnChanges

Quindi dovresti usare ngOnInit se l’elaborazione di inizializzazione si basa sui collegamenti del componente (ad esempio, i parametri del componente definiti con @Input ), altrimenti il ​​costruttore sarebbe sufficiente …

OK, prima di tutto ngOnInit fa parte del ciclo di vita Angular , mentre il constructor fa parte della class JavaScript ES6 , quindi la differenza principale inizia proprio da qui! …

Guarda il grafico sottostante che ho creato che mostra il ciclo di vita di Angular.

ngOnInit vs costruttore

In Angular2 + usiamo il constructor per fare il DI(Dependency Injection) per noi, mentre in Angular 1 stava accadendo attraverso la chiamata al metodo String e controllando quale dipendenza era stata iniettata.

Come vedi nel diagramma sopra, ngOnInit sta accadendo dopo che il costruttore è pronto e ngOnChnages e viene licenziato dopo che il componente è pronto per noi. In questa fase può avvenire tutta l’inizializzazione, un semplice esempio sta iniettando un servizio e lo inizia su init.

OK, condivido anche un codice di esempio da cercare, vedi come utilizziamo ngOnInit e constructor nel codice qui sotto:

 import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; @Component({ selector: 'my-app', template: `

App is running!

`, 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!'); } }

Una risposta breve e semplice sarebbe,

Constructor : il constructor è un default method eseguito ( da deafult ) quando il componente viene costruito. Quando si crea an instance di una class, verrà chiamato anche il constructor(default method) durata constructor(default method) . Quindi, in altre parole, quando il componente viene constructed or/and an instance is created constructor(default method) viene chiamato e viene chiamato il codice scritto all’interno. Fondamentalmente e generalmente in Angular2 era solito iniettare cose come services quando il componente è stato costruito per l’ulteriore utilizzo.

OnInit : ngOnInit è il hook del ciclo di vita del componente che viene eseguito prima dopo il constructor(default method) quando il componente viene inizializzato.

Quindi, il costruttore verrà chiamato per primo e Oninit verrà chiamato più tardi dopo il metodo del costruttore.

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() } } 

Risorse: hook LifeCycle

Puoi controllare questa piccola demo che mostra l’implementazione di entrambe le cose.

Per verificare questo, ho scritto questo codice, prendendo in prestito dal tutorial di 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; } } 

Uscita della console

 JS: *** User class constructor property *** JS: *** User class constructor constructor *** JS: *** Login Component Constructor *** JS: *** User class constructor ngOnInit *** JS: *** Login Component ngOnInit *** 

Aggiungerò solo una cosa importante che è stata saltata nelle spiegazioni sopra e spiega quando DEVI usare ngOnInit .

Se stai manipolando il DOM del componente tramite ad esempio ViewChildren , ContentChildren o ElementRef , i tuoi elementi nativi non saranno disponibili durante la fase di costruzione.

Tuttavia, dal momento che ngOnInit verifica una volta che il componente è stato creato e i controlli ( ngOnChanges ) sono stati richiamati, puoi accedere al DOM a questo punto.

 export class App implements OnInit { @ViewChild('myTemplate') myTemplate: TemplateRef; constructor(private elementRef: ElementRef) { // this.elementRef.nativeElement is undefined here // this.myTemplate is undefined here } ngOnInit() { // this.elementRef.nativeElement can be used from here on // this.myTemplate can be used from here on } } 

Le risposte di cui sopra non rispondono veramente a questo aspetto della domanda iniziale: che cosa è un hook del ciclo di vita? Mi ci è voluto un po ‘per capire cosa significa fino a quando ci ho pensato in questo modo.

1) Dire che il tuo componente è umano. Gli esseri umani hanno vite che includono molti stadi di vita, e poi scadiamo.

2) Il nostro componente umano potrebbe avere il seguente script del ciclo di vita: Nato, Bambino, Scuola elementare, Giovane adulto, Adulto di mezza età, Adulto anziano, Morto, Smaltito.

3) Di ‘che vuoi avere una funzione per creare figli. Per evitare che questo diventi complicato e piuttosto divertente, si desidera che la propria funzione venga chiamata solo durante la fase Young Adult della vita dei componenti umani. Quindi sviluppi un componente attivo solo quando il componente genitore si trova nella fase Giovani adulti. Gli hook ti aiutano a farlo segnalando quella fase della vita e lasciando che il tuo componente agisca su di essa.

Cose divertenti. Se lasci che la tua immaginazione vada effettivamente a codificare qualcosa del genere, diventa complicato e divertente.

Come molti altri linguaggi, puoi inizializzare le variabili a livello di class, costruttore o metodo. Spetta allo sviluppatore decidere cosa è meglio nel loro caso particolare. Ma di seguito sono elencate le migliori pratiche quando si tratta di decidere.

Variabili di livello di class

Solitamente, dichiarerai qui tutte le tue variabili che saranno usate nel resto del tuo componente. Puoi inizializzarli se il valore non dipende da nient’altro, o usare la parola chiave const per creare costanti se non cambieranno.

 export class TestClass{ let varA: string = "hello"; } 

Costruttore

Normalmente è meglio non fare nulla nel costruttore e usarlo solo per le classi che verranno iniettate. Il più delle volte il tuo costruttore dovrebbe assomigliare a questo:

  constructor(private http: Http, private customService: CustomService) {} 

questo creerà automaticamente le variabili di livello di class, così avrai accesso a customService.myMethod() senza doverlo fare manualmente.

NgOnInit

NgOnit è un hook del ciclo di vita fornito dal framework Angular 2. Il tuo componente deve implementare OnInit per poterlo utilizzare. Questo hook del ciclo di vita viene chiamato dopo che il costruttore viene chiamato e tutte le variabili sono inizializzate. La maggior parte della tua inizializzazione dovrebbe andare qui. Avrai la certezza che Angular ha inizializzato correttamente il tuo componente e puoi iniziare a fare qualsiasi logica tu abbia bisogno in OnInit rispetto a fare cose quando il tuo componente non ha finito di caricare correttamente.

Ecco un’immagine che dettaglia l’ordine di ciò che viene chiamato:

inserisci la descrizione dell'immagine qui

https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html

TLDR

Se si utilizza il framework Angular 2 e è necessario interagire con determinati eventi del ciclo di vita, utilizzare i metodi forniti dal framework per evitare problemi.

La principale differenza tra il costruttore e ngOnInit è che ngOnInit è l’ hook del ciclo di vita e viene eseguito dopo il costruttore. Il modello interpolato del componente e i valori iniziali di input non sono disponibili nel costruttore, ma sono disponibili in ngOnInit .

La differenza pratica è come ngOnInit influenza il modo in cui il codice è strutturato. La maggior parte del codice di inizializzazione può essere spostato su ngOnInit , a condizione che ciò non crei condizioni di competizione .

Costruttore antipattern

Una notevole quantità di codice di inizializzazione rende difficile estendere, leggere e testare il metodo di costruzione.

Una solita ricetta per separare la logica di inizializzazione dal costruttore di classi è spostarla su un altro metodo come init :

 class Some { constructor() { this.init(); } init() {...} } 

ngOnInit può servire a questo scopo in componenti e direttive:

 constructor( public foo: Foo, /* verbose list of dependencies */ ) { // time-sensitive initialization code this.bar = foo.getBar(); } ngOnInit() { // rest of initialization code } 

Iniezione di dipendenza

Il ruolo primario dei costruttori di classi in Angular è l’iniezione di dipendenza. I costruttori vengono anche utilizzati per l’annotazione DI in TypeScript. Quasi tutte le dipendenze sono assegnate come proprietà all’istanza della class.

Il costruttore medio di componenti / direttive è già abbastanza grande perché può avere una firma multilinea a causa delle dipendenze, mettendo la logica di inizializzazione non necessaria all’ quadro del costruttore che contribuisce all’antagonismo.

Inizializzazione asincrona

Il costruttore di inizializzazione asincrono può spesso essere considerato antipattern e avere un odore perché l’istanza di class termina prima che la routine asincrona lo faccia, e questo può creare condizioni di competizione. Se non è il caso, ngOnInit e altri hook del ciclo di vita sono posti migliori per questo, in particolare perché possono trarre vantaggio dalla syntax 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); } } 

Se ci sono condizioni di gara (incluso quello in cui un componente non dovrebbe apparire sull’errore di inizializzazione), la routine di inizializzazione asincrona dovrebbe aver luogo prima dell’istanziazione dei componenti e deve essere spostata sul componente principale, sulla protezione del router, ecc.

Test unitario

ngOnInit è più flessibile di un costruttore e offre alcuni vantaggi per i test unitari che sono spiegati in dettaglio in questa risposta .

Considerando che ngOnInit non viene chiamato automaticamente sulla compilazione dei componenti nei test unitari, i metodi chiamati in ngOnInit possono essere spiati o derisi dopo l’istanziazione dei componenti.

In casi eccezionali, ngOnInit può essere interamente sottoposto a ngOnInit per fornire isolamento per altre unità componenti (ad esempio, alcune logiche di template).

Eredità

Le classi figlio possono solo aumentare i costruttori, non sostituirli.

Poiché this non può essere definito prima di super() , ciò pone delle restrizioni sulla precedenza di inizializzazione.

Considerando che il componente o la direttiva angular utilizza ngOnInit per la logica di inizializzazione insensibile al tempo, le classi super.ngOnInit() possono scegliere se viene chiamato super.ngOnInit() e quando:

 ngOnInit() { this.someMethod(); super.ngOnInit(); } 

Ciò sarebbe imansible da implementare con il solo costruttore.

Angular 2 Costruttori: –

  1. Il costruttore è un metodo predefinito eseguito quando il componente viene costruito.
  2. Il costruttore è una funzione typescript e viene utilizzato solo per le istanze di classi e non ha nulla a che fare con Angular 2.
  3. Il costruttore ha chiamato la prima volta prima di ngOnInit ().

Angular 2 ngOnInit: –

  1. L’evento ngOnInit è un metodo di evento del ciclo di vita Angular 2 che viene chiamato dopo i primi ngOnChanges e il metodo ngOnInit è utilizzato per i parametri definiti con @Input altrimenti il ​​costruttore è OK.

  2. Il ngOnInit viene chiamato dopo il costruttore e ngOnInit viene chiamato dopo il primo ngOnChanges.

  3. Il ngOnChanges viene chiamato quando un valore di bind di input o output cambia.

Il seguente diagramma spiega il ciclo di bugie di Angular. Da ciò puoi avere un’idea sull’ordine in cui è chiamato ognuno.

inserisci la descrizione dell'immagine qui

Il costruttore è un metodo in JavaScript ed è considerato come una caratteristica della class in es6. Quando la class è istanziata, esegue immediatamente la funzione di costruzione se è usata nel framework Angolare o no. Quindi viene chiamata dal motore JavaScript e Angular non ha controllo su quello.

 import {Component} from '@angular/core'; @Component({}) class CONSTRUCTORTEST { //This is called by Javascript not the Angular. constructor(){ console.log("view constructor initialised"); } } 

La class “ConstructorTest” viene istanziata di seguito, quindi chiama internamente il costruttore (Tutto ciò avviene con JavaScript (es6) no Angular).

 new CONSTRUCTORTEST(); 

Questo è il motivo per cui esiste un hook del ciclo di vita ngOnInit nei rendering Angular.ngOnInit quando Angular ha terminato di inizializzare il componente.

 import {Component} from '@angular/core'; @Component({}) class NGONINITTEST implements onInit{ constructor(){} //ngOnInit calls by Angular ngOnInit(){ console.log("Testing ngOnInit"); } } 

Per prima cosa istanziamo la class come di seguito che accade alle esecuzioni immediate del metodo di costruzione.

 let instance = new NGONINITTEST(); 

ngOnInit è chiamato da Angular quando necessario come di seguito:

 instance.ngOnInit(); 

Ma potresti chiedere perché stiamo usando il costruttore in Angular?

La risposta è iniezioni di dipendenze . Come accennato prima, le chiamate del costruttore da parte del motore JavaScript immediatamente quando la class viene istanziata (prima di chiamare ngOnInit da Angular), quindi typescript ci aiuta a ottenere il tipo di dipendenze definite nel costruttore e infine dice Angolare quale tipo di dipendenze vogliamo utilizzare in quel componente specifico.

Due cose da osservare qui:

  1. Il costruttore viene chiamato ogni volta che viene creato un object di quella class.
  2. ngOnInit chiamato una volta che il componente è stato creato.

Entrambi hanno un’usabilità diversa.

Entrambi i metodi hanno diversi obiettivi / responsabilità. Il compito del costruttore (che è una funzione supportata dalla lingua) è assicurarsi che l’invarianza di rappresentazione sia valida. Altrimenti indicato per assicurarsi che l’istanza sia valida dando valori corretti ai membri. Spetta allo sviluppatore decidere cosa significa “corretto”.

Il compito del metodo onInit () (che è un concetto angular) è di consentire invocazioni di metodi su un object corretto (rappresentazione invariante). A turno, ogni metodo dovrebbe assicurarsi che l’invarianza di rappresentazione resti valida quando il metodo termina.

Il costruttore deve essere usato per creare oggetti ‘corretti’, il metodo onInit ti dà l’opportunità di invocare chiamate di metodo in un’istanza ben definita.

Costruttore: il metodo di costruzione su una class ES6 (o TypeScript in questo caso) è una funzione di una class stessa, piuttosto che una funzione Angolare. È fuori controllo da parte di Angular quando viene invocato il costruttore, il che significa che non è un hook adatto per farti sapere quando Angular ha terminato di inizializzare il componente. Il motore JavaScript chiama il costruttore, non direttamente Angolare. Ecco perché è stato creato l’hook del ciclo di vita ngOnInit (e $ onInit in AngularJS). Tenendo presente questo, c’è uno scenario adatto per l’utilizzo del costruttore. Questo è il momento in cui vogliamo utilizzare l’iniezione di dipendenza, essenzialmente per “cablare” le dipendenze nel componente.

Poiché il costruttore è inizializzato dal motore JavaScript e TypeScript ci consente di dire ad Angular quali dipendenze richiediamo per essere mappate su una proprietà specifica.

ngOnInit è puramente lì per darci un segnale che Angular ha finito di inizializzare il componente.

Questa fase include il primo passaggio a Rilevamento modifiche rispetto alle proprietà che potremmo associare al componente stesso, ad esempio utilizzando un decoratore @Input ().

Per questo motivo, le proprietà @Input () sono disponibili all’interno di ngOnInit, tuttavia sono indefinite all’interno del costruttore, in base alla progettazione

constructor () è il metodo predefinito nel ciclo di vita del componente e viene utilizzato per l’iniezione delle dipendenze. Il costruttore è una funzione typescript.

ngOnInit () viene chiamato dopo il costruttore e ngOnInit viene chiamato dopo i primi ngOnChanges.

ie Constructor () -> ngOnChanges () -> ngOnInit ()

come menzionato sopra, ngOnChanges () viene chiamato quando cambia un valore di binding di input o output.

constructor() è usato per fare l’iniezione di dipendenza.

ngOnInit() , ngOnChanges() e ngOnDestroy() ecc. sono metodi del ciclo di vita. ngOnChanges() sarà il primo ad essere chiamato, prima di ngOnInit() , quando il valore di una proprietà legata cambia, NON verrà chiamato se non ci sono cambiamenti. ngOnDestroy() viene chiamato quando il componente viene rimosso. Per usarlo, OnDestroy deve essere implement dalla class.

Nei cicli di vita angolari

1) L’iniettore angular rileva il parametro del costruttore (s) e la class di istanza.

2) Ciclo di vita della chiamata angular successiva

Ganci angolari del ciclo di vita

ngOnChanges -> Richiama i parametri direttive vincolanti.

ngOnInit -> Inizia il rendering angular …

Chiamare un altro metodo con stato del ciclo di vita angular.