Differenza tra costruttore e ngOnInit


1075

Angolare fornisce il gancio del ciclo di vita ngOnInitper impostazione predefinita.

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


11
ehi, controlla la mia risposta che spiega la differenza dal punto di vista dei meccanismi interni di Angular
Max Koretskyi


1
@MaximKoretskyi, il tuo link è morto.
Yash Capoor,

Risposte:


1112

Il Constructorè un metodo predefinito della classe che viene eseguito quando la classe viene istanziata e assicura la corretta inizializzazione campi nella classe e le sue sottoclassi. Angular, o meglio Dependency Injector (DI), analizza i parametri del costruttore e quando crea una nuova istanza chiamandola 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 Angular per indicare che Angular è stato creato creando il componente.

Dobbiamo importare in OnInitquesto modo per usarlo (in realtà l'implementazione OnInitnon è obbligatoria ma considerata una buona pratica):

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

quindi per farci usare il metodo OnInit, dobbiamo implementare la classe in questo modo:

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à associate ai dati della direttiva sono state verificate per la prima volta e prima che uno dei suoi figli sia stato verificato. Viene invocato una sola volta quando viene istanziata la direttiva.

Principalmente usiamo ngOnInittutte le inizializzazioni / dichiarazioni ed evitiamo che cose funzionino nel costruttore. Il costruttore dovrebbe essere usato solo per inizializzare i membri della classe, ma non dovrebbe fare un vero "lavoro".

Quindi dovresti usare constructor()per impostare Dependency Injection e non molto altro. ngOnInit () è il posto migliore per "iniziare" - è dove / quando vengono risolti i collegamenti dei componenti.

Per maggiori informazioni consultare qui:


62
Esattamente, la maggior parte (o addirittura tutte) le lingue basate sulla classe hanno dei contruttori per garantire un corretto ordine di inizializzazione, specialmente delle classi che estendono altre classi in cui possono sorgere problemi abbastanza difficili, come i campi finali (non so se TS li ha) e simili. I costruttori non sono correlati ad Angular2, sono una funzione TypeScript. Gli hook del ciclo di vita vengono chiamati da Angular dopo che è avvenuta l'inizializzazione o quando qualche evento è accaduto per consentire al componente di agire in determinate situazioni e dargli la possibilità di eseguire alcune attività nei momenti giusti.
Günter Zöchbauer

13
C'è una citazione a blocchi in angular.io/docs/ts/latest/guide/server-communication.html che spiega anche questo: "I componenti sono più facili da testare ed eseguire il debug quando i loro costruttori sono semplici e tutto il lavoro reale (specialmente chiamando un server remoto) viene gestito in un metodo separato. " - In questo caso quel metodo è ngOnInit ()
yoonjesung

3
è un hook del ciclo di vita chiamato da Angular2 per indicare che Angular è stato creato creando il componente. - non è esattamente quello. segnala che ha inizializzato i binding. Il componente è stato creato in precedenza. Vedi la mia risposta
Max Koretskyi,

22
Come per tutte le "migliori pratiche", penso che sarebbe una buona idea spiegare anche perché non dovresti fare "lavoro" nel costruttore. Questo articolo del caposquadra angolare è denso ma può aiutare: misko.hevery.com/code-reviewers-guide/… Inoltre, una minore importanza dovrebbe essere posta sugli incantesimi richiesti per implementare OnInit (questo è facile da trovare) e altro su il fatto critico che i collegamenti ai dati non sono disponibili nel costruttore.
Reikim,

2
Se la modalità rigorosa è vera in tsconfig.jsonfile simili "strict": true, è necessario inizializzare i membri della classe in constructor, non in ngOnitsimili FormGroup.
Rohit Sharma,

174

L'articolo La differenza essenziale tra Costruttore e ngOnInit in Angular esplora la differenza da più prospettive. Questa risposta fornisce la spiegazione della differenza più importante relativa al processo di inizializzazione del componente che mostra anche i diversi nell'uso.

Il processo angolare del bootstrap consiste nelle due fasi principali:

  • costruzione dell'albero dei componenti
  • esecuzione del rilevamento delle modifiche

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

Quando Angular costruisce l'albero dei componenti l'iniettore del modulo radice è già configurato in modo da poter iniettare qualsiasi dipendenza globale. Inoltre, quando Angular crea un'istanza di una classe componente figlio, l'iniettore per il componente padre è già impostato in modo da poter iniettare i provider definiti sul componente padre incluso il componente padre stesso. I costruttori di componenti sono l'unico metodo che viene chiamato nel contesto dell'iniettore, quindi se hai bisogno di una dipendenza è l'unico posto per ottenere quelle dipendenze.

Quando Angular avvia il rilevamento delle modifiche, viene costruito l'albero dei componenti e sono stati chiamati i costruttori per tutti i componenti dell'albero. Inoltre, i nodi modello di ogni componente vengono aggiunti al DOM. Il @Inputmeccanismo di comunicazione viene elaborato durante il rilevamento delle modifiche, quindi non puoi aspettarti di avere le proprietà disponibili nel costruttore. Sarà disponibile dopo ngOnInit.

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

<my-app>
   <child-comp [i]='prop'>

Quindi Angular inizia l'avvio del bootstrap dell'applicazione. Come ho già detto, crea prima le classi per ciascun componente. Quindi chiama MyAppComponentcostruttore. Crea inoltre un nodo DOM che è l'elemento host del my-appcomponente. Quindi procede alla creazione di un elemento host per il costruttore child-compe chiamante ChildComponent. In questa fase non si occupa davvero dell'associazione di iinput e di eventuali hook del ciclo di vita. Quindi, al termine di questo processo, Angular termina con la seguente struttura ad albero delle viste dei componenti:

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

Solo allora esegue il rilevamento delle modifiche e aggiorna i binding per my-appe chiama ngOnInitla classe MyAppComponent. Quindi procede con l'aggiornamento dei bind per child-compe chiama ngOnInitla classe ChildComponent.

È possibile eseguire la logica di inizializzazione in un costruttore o in ngOnInitbase a ciò che è necessario disponibile. Ad esempio l'articolo Ecco come ottenere ViewContainerRef prima che la query @ViewChild venga 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:


33
questa dovrebbe essere la risposta accettata. in realtà spiega il PERCHÉ piuttosto che ripetere mantra e affermare the constructor should only be used to inject dependencies.
Stavm,

1
@ yannick1976, grazie!
Dai

@Flobacca, per favore, puoi riformulare la domanda, è difficile capire cosa stai chiedendo
Max Koretskyi,

Per favore correggimi se sbaglio. Ho capito che l'albero dei componenti è stato prima costruito e poi cambiato il processo di rilevamento. È stato scritto prima il costruttore AppComponent viene chiamato (insieme alle dipendenze risolte), quindi il costruttore ChildComponent viene chiamato (insieme alle dipendenze), quindi i collegamenti di input per AppComponent e quindi viene chiamato OnInit. Ma la mia preoccupazione è se aggiungo hook del ciclo di vita ad entrambi i componenti il ​​flusso è AppComponentConstructor - -> AppComponentOnInit - → ChildComponentConstructor - → ChildComponentOnInit Perché AppComponentOnInit viene chiamato prima di ChildComponentConstructor
user2485435

1
@MaxKoretskyiakaWizard avevi ragione. Ho fatto qualche errore nella configurazione della mia applicazione. funziona come descritto da te. angular-c7zjsx.stackblitz.io
user2485435

96

Penso che il miglior esempio sarebbe l'utilizzo dei servizi. Diciamo che voglio prendere i dati dal mio server quando il mio componente viene 'attivato'. Diciamo che voglio anche fare alcune cose aggiuntive ai dati dopo averlo ricevuto dal server, forse ricevo un errore e voglio registrarlo in modo diverso.

È davvero facile con ngOnInit su un costruttore, inoltre limita il numero di livelli di callback che devo aggiungere alla mia applicazione.

Per esempio:

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


}

con il mio costruttore potrei semplicemente chiamare il mio _userService e popolare la mia lista_utente, ma forse voglio fare qualche cosa in più con esso. Come assicurati che tutto sia maiuscolo, non sono del tutto sicuro di come i miei dati vengano trasmessi.

Quindi rende molto più facile usare 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();
    };


}

Lo rende molto più facile da vedere, e quindi chiamo la mia funzione all'interno del mio componente quando eseguo l'inizializzazione invece di dover cercare da qualche altra parte. In realtà è solo un altro strumento che puoi usare per semplificare la lettura e l'uso in futuro. Inoltre trovo davvero una cattiva pratica mettere chiamate di funzione all'interno di un costruttore!


Il tuo esempio potrebbe essere semplificato se hai appena impostato user_list su Observable. Angular2 ha il tubo asincrono, quindi non ci sarebbero problemi lì.
DarkNeuron,

@Morgan, solo per me imparare una piccola cosa qui, perché prima crei una funzione getUserse poi la inserisci ngOnInit? Non è meno codice semplicemente scriverlo in ngOnInit? Mi sto solo chiedendo perché le persone lo fanno in questo modo? È così che puoi riutilizzare il codice se lo desideri anche tu? Grazie.
Alfa Bravo

31
Come si vede nella risposta sotto, questo non fa differenza se è nel costruttore. Questa non è una vera risposta allo scopo.
Jimmy Kane,

8
Non vedo come questo risponda alla domanda. Perché non puoi semplicemente inserire il codice nel constructor?
CodyBugstein,

1
@ Morgan perché non puoi semplicemente farloconstructor(private _userService: UserService){ this.getUsers(); };
Ashley,

82

OK, prima di tutto ngOnInitfa parte del ciclo di vita angolare , mentre constructorfa parte della classe JavaScript ES6 , quindi la differenza principale inizia proprio qui! ...

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

ngOnInit vs constructor

In Angular2 + usiamo constructorfare DI(Dependency Injection)per noi, mentre in Angular 1 stava accadendo chiamando il metodo String e controllando quale dipendenza era stata iniettata.

Come vedi nel diagramma sopra, ngOnInitsta succedendo dopo che il costruttore è pronto ngOnChnagese viene licenziato dopo che il componente è pronto per noi. Tutta l'inizializzazione può avvenire in questa fase, un semplice campione sta iniettando un servizio e lo inizializza su init.

OK, condivido anche un codice di esempio per farti guardare, vedere come ci usiamo ngOnInite constructornel codice qui sotto:

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

1
Grazie. questa dovrebbe essere la risposta migliore.
Don Dilanga,

58

Il primo (costruttore) è correlato all'istanza di classe e non ha nulla a che fare con Angular2. Voglio dire, un costruttore può essere usato su qualsiasi classe. È possibile inserire un processo di inizializzazione per l'istanza appena creata.

Il secondo corrisponde a un gancio del ciclo di vita dei componenti Angular2:

Citato dal sito ufficiale di Angular:

  • ngOnChanges viene chiamato quando cambia un valore di associazione input o output
  • ngOnInit viene chiamato dopo il primo ngOnChanges

Quindi dovresti usare ngOnInitse l'elaborazione di inizializzazione si basa su associazioni del componente (ad esempio i parametri del componente definiti con @Input), altrimenti il ​​costruttore sarebbe sufficiente ...


49

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

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

Tuttavia, poiché si ngOnInitverifica dopo che il componente è stato creato e ngOnChangessono stati chiamati i controlli ( ), è possibile accedere al DOM a questo punto.

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

3
No. Per @ViewChildrenin particolare, è necessario utilizzare il ngAfterViewInitmetodo Vedi qui: stackoverflow.com/questions/46314734/...
AsGoodAsItGets

1
Grazie, @AsGoodAsItGets per averlo segnalato. Ora ho migliorato la risposta
Miroslav Jonas il

38

La risposta breve e semplice sarebbe

Constructor: constructorè una default methodcorsa ( per sordo ) durante la costruzione del componente. Quando crei an instanceuna classe, anche quel tempo constructor(default method)verrebbe chiamato. Quindi, in altre parole, quando constructed or/and an instance is created constructor(default method)viene chiamato il componente e viene chiamato il relativo codice scritto all'interno. Fondamentalmente e generalmente in Angular2esso usato per iniettare cose come servicesquando il componente viene costruito per un ulteriore utilizzo.

OnInit: ngOnInit è l'hook del ciclo di vita del componente che viene eseguito per primo dopo constructor(default method)l'inizializzazione del componente.

Quindi, il tuo costruttore verrà chiamato per primo e Oninit verrà chiamato in seguito 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: gancio per il ciclo di vita

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


5
Penso che "il costruttore sia qualcosa che viene eseguito o chiamato quando il componente viene inizializzato". è fuorviante. Il costruttore è una caratteristica della classe e non del componente. Direi che l'istanza della classe diventa un componente solo dopo che il costruttore è stato chiamato e Angular ha fatto l'inizializzazione.
Günter Zöchbauer

Sì, è stata modificata la dichiarazione che è possibile controllare ora.
Micronyks

1
Hmm, IMHO è sempre lo stesso "costruttore (metodo predefinito) che viene eseguito o chiamato quando viene costruito il componente". Non viene chiamato solo quando viene costruito un componente, ma anche per servizi o quando new MyClass()viene eseguito un codice simile . Penso che sia fuorviante affermare che i costruttori riguardano i componenti, riguardano le classi e inizializzano le istanze di queste classi. Un componente sembra essere una tale classe. Altrimenti penso che sia una buona risposta.
Günter Zöchbauer,

2
Si assolutamente. Hai dimenticato di dire che quando crei un oggetto di una classe anche quel tempo constructorverrebbe chiamato. Ma questa risposta è stata scritta nel contesto angular2. Per conoscere la risposta migliore devi conoscere le nozioni di base di OOP. Continuerò ad aggiornare la risposta.
Micronyks

@ GünterZöchbauer, non penso che sia un'affermazione corretta che è una caratteristica della classe e non del componente . Dal punto di vista del linguaggio di programmazione sì, questo è corretto. Ma posso lavorare con successo con i componenti senza alcun aggancio del ciclo di vita. Ma non posso lavorare con un componente senza un costruttore se ho bisogno di DI perché è l'unico posto iniettabile. Vedi la mia risposta
Max Koretskyi,

20

Come molte altre lingue, è possibile inizializzare le variabili a livello di classe, il costruttore o un metodo. Spetta allo sviluppatore decidere cosa è meglio nel loro caso particolare. Ma di seguito è riportato un elenco delle migliori pratiche quando si tratta di decidere.

Variabili a livello di classe

Di solito, dichiarerai qui tutte le variabili che verranno utilizzate nel resto del 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 è consigliabile non fare nulla nel costruttore e usarlo solo per le classi che verranno iniettate. Il più delle volte il tuo costruttore dovrebbe apparire così:

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

questo creerà automaticamente le variabili a livello di classe, quindi avrai accesso a customService.myMethod()senza farlo manualmente.

NgOnInit

NgOnit è un hook del ciclo di vita fornito dal framework Angular 2. Il componente deve essere implementato OnInitper poterlo utilizzare. Questo hook del ciclo di vita viene chiamato dopo che il costruttore è stato 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 di cui hai bisogno OnInitrispetto a fare cose quando il tuo componente non ha finito di caricarsi correttamente.

Ecco un'immagine che descrive in dettaglio l'ordine di ciò che viene chiamato:

inserisci qui la descrizione dell'immagine

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.


19

Per verificarlo, 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 console

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

18

La differenza principale tra il costruttore e ngOnInitche 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 è in che modo ngOnInitinfluenza la struttura del codice. La maggior parte codice di inizializzazione può essere spostato ngOnInit- a patto che ciò non crea condizioni di gara .

Antipasto del costruttore

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 della classe è di spostarla in 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 principale dei costruttori di classi in Angular è l'iniezione di dipendenza. I costruttori sono anche usati per l'annotazione DI in TypeScript. Quasi tutte le dipendenze vengono assegnate come proprietà all'istanza di classe.

Il costruttore medio di componenti / direttive è già abbastanza grande perché può avere una firma multilinea a causa delle dipendenze, mettendo una logica di inizializzazione non necessaria al corpo del costruttore contribuisce all'antipasto.

Inizializzazione asincrona

Il costruttore di inizializzazione asincrona può spesso essere considerato antipattern e avere odore perché l'istanza di classe termina prima della routine asincrona e questo può creare condizioni di competizione. In caso contrario, ngOnInite altri hook del ciclo di vita sono posti migliori per questo, in particolare perché possono beneficiare della asyncsintassi:

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 competizione (inclusa quella in cui un componente non dovrebbe apparire in caso di errore di inizializzazione), la routine di inizializzazione asincrona dovrebbe aver luogo prima dell'istanza del componente e essere spostata sul componente genitore, sulla protezione del router, ecc.

Test unitari

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

Considerando che ngOnInitnon viene chiamato automaticamente durante la compilazione dei componenti nei test unitari, i metodi chiamati ngOnInitpossono essere spiati o derisi dopo l'istanza del componente.

In casi eccezionali ngOnInitpuò essere completamente eliminato per fornire l'isolamento per altre unità componenti (ad esempio, una logica di modello).

Eredità

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

Poiché thisnon è possibile fare riferimento in precedenza super(), ciò pone delle restrizioni sulla precedenza di inizializzazione.

Considerando che il componente angolare o la direttiva utilizza ngOnInitper la logica di inizializzazione insensibile al tempo, le classi figlio possono scegliere se super.ngOnInit()chiamare e quando:

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

Ciò sarebbe impossibile da attuare solo con il costruttore.


12

Le risposte di cui sopra non rispondono realmente a questo aspetto della domanda originale: cos'è un gancio per il ciclo di vita? Mi ci è voluto un po 'di tempo per capire cosa significa che non ci ho pensato in questo modo.

1) Di 'che il tuo componente è un essere umano. Gli esseri umani hanno vite che includono molte fasi della vita, e poi scadiamo.

2) La nostra componente umana potrebbe avere il seguente copione del ciclo di vita: Born, Baby, Grade School, Young Adult, Mid-age Adult, Senior Adult, Dead, Disposed.

3) Di 'che vuoi avere una funzione per creare bambini. Per evitare che ciò diventi complicato e piuttosto umoristico, vuoi che la tua funzione venga chiamata solo durante lo stadio della Giovane Vita umana della componente umana. Quindi sviluppi un componente che è attivo solo quando il componente genitore è nella fase Giovani adulti. I ganci ti aiutano a farlo segnalando quello stadio della vita e lasciando che il tuo componente agisca su di esso.

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


7

Il costruttore è un metodo in JavaScript ed è considerato come una caratteristica della classe in es6. Quando la classe viene istanziata, esegue immediatamente il costruttore indipendentemente dal fatto che sia utilizzata in framework angolare o meno, 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 classe "ConstructorTest" è istanziata di seguito, quindi chiama internamente il costruttore (tutto ciò accade con JavaScript (es6) non angolare).

new CONSTRUCTORTEST();

Questo è il motivo per cui esiste un hook del ciclo di vita ngOnInit in Angular.ngOnInit esegue il rendering quando Angular ha terminato l'inizializzazione del componente.

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

Prima di tutto creiamo un'istanza della classe come di seguito che si verifica nelle esecuzioni immediate del metodo del costruttore.

let instance = new NGONINITTEST();

ngOnInit viene chiamato da Angular quando necessario come di seguito:

instance.ngOnInit();

Ma potresti chiederti perché stiamo usando il costruttore in Angolare?

La risposta sono le iniezioni di dipendenze . Come è stato menzionato prima, il costruttore chiama immediatamente il motore JavaScript quando la classe viene istanziata (prima di chiamare ngOnInit da Angular), quindi typescript ci aiuta a ottenere il tipo di dipendenze che sono definite nel costruttore e infine dice Angolare quale tipo di dipendenze vogliamo usare in quel componente specifico.


7

Due cose da osservare qui:

  1. Il costruttore viene chiamato ogni volta che viene creato un oggetto di quella classe.
  2. ngOnInit chiamato una volta creato il componente.

Entrambi hanno usabilità diversa.


5

constructor () è il metodo predefinito nel ciclo di vita dei componenti e viene utilizzato per l'iniezione delle dipendenze. Il costruttore è una caratteristica dattiloscritta.

ngOnInit () viene chiamato dopo il costruttore e ngOnInit viene chiamato dopo il primo ngOnChanges.

vale a dire:

Costruttore () -->ngOnChanges () -->ngOnInit ()

come detto sopra ngOnChanges()viene chiamato quando cambia un valore di associazione input o output.


4

Entrambi i metodi hanno obiettivi / responsabilità diversi. Il compito del costruttore (che è una funzione supportata dal linguaggio) è assicurarsi che l'invariante della rappresentazione sia valida. Altrimenti dichiarato per assicurarsi che l'istanza sia valida fornendo valori corretti ai membri. Spetta allo sviluppatore decidere cosa significa "corretto".

Il compito del metodo onInit () (che è un concetto angolare) è consentire invocazioni di metodi su un oggetto corretto (rappresentazione invariante). Ogni metodo dovrebbe a sua volta assicurarsi che l'invariante della rappresentazione sia valida al termine del metodo.

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


4

Funzione di costruzione: il metodo di costruzione su una classe ES6 (o TypeScript in questo caso) è una caratteristica di una classe stessa, piuttosto che una funzione angolare. È fuori dal controllo di Angular quando viene invocato il costruttore, il che significa che non è un hook adatto per farti sapere quando Angular ha terminato l'inizializzazione del 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 ciò, esiste uno scenario adatto per l'utilizzo del costruttore. Questo è quando vogliamo utilizzare l'iniezione delle dipendenze, essenzialmente per "cablare" le dipendenze nel componente.

Dato che il costruttore è inizializzato dal motore JavaScript e TypeScript ci consente di dire ad Angular quali dipendenze sono necessarie per essere mappate rispetto a una proprietà specifica.

ngOnInit è puramente lì per darci un segnale che Angular ha terminato l'inizializzazione del componente.

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

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


2

Il costruttore è il primo e succede a volte quando i dati @input sono nulli! quindi usiamo il costruttore per dichiarare i servizi e ngOnInit avviene dopo. Esempio per contrutor:

 constructor(translate: TranslateService, private oauthService: OAuthService) {
    translate.setDefaultLang('En');
        translate.use('En');}

Esempio per onInit:

ngOnInit() {
    this.items = [
      { label: 'A', icon: 'fa fa-home', routerLink: ['/'] },
      { label: 'B', icon: 'fa fa-home', routerLink: ['/'] }]
}

Penso che onInit sia come InitialComponents () in winForm.


1

Nei cicli di vita angolari

1) L'iniettore angolare rileva i parametri del costruttore e la classe di istanza.

2) Prossimo ciclo di vita della chiamata angolare

Ganci angolari per il ciclo di vita

ngOnChanges -> Richiama l'associazione dei parametri della direttiva.

ngOnInit -> Avvia rendering angolare ...

Chiamare un altro metodo con lo stato del ciclo di vita angolare.


1

Il constructorviene chiamato quando "instanciates / costrutti" angolari del componente. Il ngOnInitmetodo è un hook che rappresenta la parte di inizializzazione del ciclo di vita del componente. Una buona pratica è di usarlo solo per l' iniezione di servizio :

constructor(private 
    service1: Service1,
    service2: Service2
){};

Anche se è possibile, non dovresti fare "lavoro" all'interno. Se si desidera avviare alcune azioni che devono verificarsi durante l'inizializzazione del componente, utilizzare ngOnInit:

ngOnInit(){
    service1.someWork();
};

Inoltre, le azioni che coinvolgono le proprietà di input , provenienti da un componente genitore, non possono essere eseguite nel contrettore. Dovrebbero essere inseriti nel ngOnInitmetodo o in un altro gancio. È lo stesso per l'elemento correlato alla vista (il DOM), ad esempio elementi 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
};

0

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

ngOnInit(), ngOnChanges()E ngOnDestroy()così via sono i metodi del ciclo di vita. ngOnChanges()sarà il primo a essere chiamato, prima ngOnInit(), quando il valore di una proprietà associata cambia, NON verrà chiamato se non vi sono cambiamenti. ngOnDestroy()viene chiamato quando il componente viene rimosso. Per usarlo, OnDestroydeve essere implementedito dalla classe.


1
d'accordo, questo è breve e chiaro. Ad esempio, constructor () serve per aggiungere oggetti di servizio, ngOnInit () serve per manipolare componenti con le necessarie chiamate di funzioni di servizio.
Steve

0

Ho trovato la risposta e ho provato a tradurla in inglese: questa domanda è ancora sorta, anche nelle interviste tecniche. In effetti, c'è una grande somiglianza tra i due, ma ci sono anche alcune differenze.

  • Il costruttore fa parte di ECMAScript. D'altra parte ngOnInit () è una nozione di angolare.

  • Possiamo chiamare i costruttori in tutte le classi anche se non usiamo Angular

  • Ciclo di vita: il costruttore viene chiamato prima di ngOnInt ()

  • Nel costruttore non possiamo chiamare elementi HTML. Tuttavia, in ngOnInit () possiamo.

  • In genere, chiamate di servizi in ngOnInit () e non nel costruttore

    Fonte: http://www.angular-tuto.com/Angular/Component#Diff


0

Costruttore

La funzione di costruzione viene fornita con ogni classe, i costruttori non sono specifici dell'Angolare ma sono concetti derivati ​​da progetti orientati agli oggetti. Il costruttore crea un'istanza della classe componente.

OnInit

La ngOnInitfunzione è uno dei metodi del ciclo di vita di una componente angolare. I metodi (o ganci) del ciclo di vita nei componenti angolari consentono di eseguire un pezzo di codice in diverse fasi della vita di un componente. A differenza del metodo del costruttore, il ngOnInitmetodo proviene da un'interfaccia angolare ( OnInit) che il componente deve implementare per utilizzare questo metodo. Il ngOnInitmetodo viene chiamato poco dopo la creazione del componente.


0

Il costruttore viene eseguito quando la classe viene istanziata. Non ha nulla a che fare con l'angolare. È la funzionalità di Javascript e Angular non ha il controllo su di esso

NgOnInit è specifico di Angular e viene chiamato quando Angular ha inizializzato il componente con tutte le sue proprietà di input

Le proprietà @Input sono disponibili sotto l'hook del ciclo di vita ngOnInit. Questo ti aiuterà a fare alcune cose di inizializzazione come ottenere dati dal server back-end ecc. Da visualizzare nella vista

Le proprietà @Input vengono visualizzate come non definite all'interno del costruttore


-1

Il costruttore è una funzione eseguita quando viene costruito il componente (o altra classe).

ngOnInit è una funzione appartenente a un gruppo di metodi del ciclo di vita dei componenti e vengono eseguiti in un momento diverso del nostro componente (ecco perché denominare il ciclo di vita). Ecco un elenco di tutti loro:

inserisci qui la descrizione dell'immagine Il costruttore verrà eseguito prima di qualsiasi funzione del ciclo di vita.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.