wake-up-neo.com

Unterschied zwischen Konstruktor und ngOnInit

Angular bietet standardmäßig einen Lebenszyklus-Hook ngOnInit.

Warum sollte ngOnInit verwendet werden, wenn wir bereits eine constructor haben?

693
Haseena P A

Die Variable Constructor ist eine Standardmethode der Klasse, die ausgeführt wird, wenn die Klasse instanziiert wird, und sorgt für die korrekte Initialisierung der Felder in der Klasse und ihrer Unterklassen. Angular oder besser Dependency Injector (DI) analysiert die Konstruktorparameter und wenn es eine neue Instanz erstellt, indem es new MyClass() aufruft, versucht es Anbieter zu finden, die den Typen der Konstruktorparameter entsprechen, löst diese auf und übergibt sie dem Konstruktor ähnlich

new MyClass(someArg);

ngOnInit ist ein Lebenszyklus-Hook, der von Angular2 aufgerufen wird, um anzuzeigen, dass Angular die Komponente erstellt hat.

Wir müssen OnInit importieren, um diese Funktion verwenden zu können (die Implementierung von OnInit ist nicht obligatorisch, wird jedoch als bewährte Methode betrachtet):

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

um die Methode von OnInit zu verwenden, müssen wir diese Klasse in der Klasse implementieren.

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

  ngOnInit(){
     //called after the constructor and called  after the first ngOnChanges() 
  }
}

Implementieren Sie diese Schnittstelle, um eine benutzerdefinierte Initialisierungslogik auszuführen, nachdem die datengebundenen Eigenschaften der Direktive initialisiert wurden. ngOnInit wird direkt nach der ersten Prüfung der datengebundenen Eigenschaften der Direktive aufgerufen. und bevor eines seiner Kinder geprüft wurde. Sie wird nur einmal aufgerufen, wenn die Direktive instanziiert wird.

Meistens verwenden wir ngOnInit für die gesamte Initialisierung/Deklaration und vermeiden, dass etwas im Konstruktor funktioniert. Der Konstruktor sollte nur zum Initialisieren von Klassenmitgliedern verwendet werden, sollte jedoch keine eigentliche "Arbeit" ausführen.

Daher sollten Sie constructor() verwenden, um Dependency Injection einzurichten, und nicht viel anderes. ngOnInit () ist ein besserer Ort zum "Starten" - dort, wo Komponenten aufgelöst werden.

Weitere Informationen finden Sie hier:

785
Pardeep Jain

Der Artikel Der wesentliche Unterschied zwischen Constructor und ngOnInit in Angular untersucht den Unterschied aus mehreren Perspektiven. Diese Antwort enthält die wichtigsten Unterschiede, die sich auf den Komponenteninitialisierungsprozess beziehen, und zeigt auch die Unterschiede in der Verwendung.

Der Angular Bootstrap-Prozess besteht aus den zwei Hauptstufen:

  • konstruktionskomponentenbaum
  • laufende Änderungserkennung

Der Konstruktor der Komponente wird aufgerufen, wenn Angular den Komponentenbaum erstellt. Alle Lebenszyklus-Hooks werden als Teil der Änderungslauferkennung aufgerufen. 

Wenn Angular einen Komponentenbaum erstellt, ist der Root-Modul-Injektor bereits konfiguriert, sodass Sie globale Abhängigkeiten einfügen können. Wenn Angular eine untergeordnete Komponentenklasse instanziiert, ist auch der Injektor für die übergeordnete Komponente bereits eingerichtet, sodass Sie Anbieter einspritzen können, die für die übergeordnete Komponente definiert sind, einschließlich der übergeordneten Komponente. Komponentenkonstruktoren sind die einzige Methode, die im Kontext des Injektors aufgerufen wird. Wenn Sie also Abhängigkeiten benötigen, können Sie diese Abhängigkeiten nur abrufen.

Wenn Angular die Änderungserkennung startet, wird der Komponentenbaum erstellt und die Konstruktoren für alle Komponenten im Baum wurden aufgerufen. Außerdem werden die Schablonenknoten jeder Komponente zum DOM hinzugefügt. Der @Input-Kommunikationsmechanismus wird während der Änderungserkennung verarbeitet, sodass Sie nicht erwarten können, dass die Eigenschaften im Konstruktor verfügbar sind. Es wird am nach ngOnInit verfügbar sein.

Lassen Sie uns ein kurzes Beispiel sehen. Angenommen, Sie haben die folgende Vorlage:

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

Angular startet also das Bootstrapping der Anwendung. Wie gesagt, erstellt es zuerst Klassen für jede Komponente. Es ruft also MyAppComponent Konstruktor auf. Außerdem wird ein DOM-Knoten erstellt, der das Host-Element der my-app-Komponente ist. Dann wird ein Host-Element für den Konstruktor child-comp erstellt und ChildComponent aufgerufen. In diesem Stadium ist es nicht wirklich mit der i-Eingabebindung und den Lebenszyklus-Hooks befasst. Nach Abschluss dieses Vorgangs erhält Angular den folgenden Baum der Komponentenansichten:

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

Erst dann werden Änderungserkennung und Aktualisierungsbindungen für my-app ausgeführt und ngOnInit für die MyAppComponent-Klasse aufgerufen. Anschließend werden die Bindungen für child-comp aktualisiert und ngOnInit für die ChildComponent-Klasse aufgerufen.

Sie können Ihre Initialisierungslogik entweder im Konstruktor oder in ngOnInit ausführen, je nachdem, was Sie benötigen. Zum Beispiel im Artikel So erhalten Sie ViewContainerRef, bevor die @ViewChild-Abfrage ausgewertet wird zeigt, welche Art von Initialisierungslogik im Konstruktor ausgeführt werden muss.

Hier einige Artikel, die Ihnen helfen, das Thema besser zu verstehen:

Ich denke, das beste Beispiel wäre die Verwendung von Diensten. Nehmen wir an, ich möchte Daten von meinem Server holen, wenn meine Komponente aktiviert wird. Nehmen wir an, ich möchte noch einige zusätzliche Daten an den Daten vornehmen, nachdem ich sie vom Server erhalten habe. Vielleicht bekomme ich einen Fehler und möchte sie anders protokollieren.

Mit ngOnInit über einen Konstruktor ist es wirklich einfach, es begrenzt auch, wie viele Callback-Layer ich meiner Anwendung hinzufügen muss.

Zum Beispiel:

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


}

mit meinem Konstruktor könnte ich einfach meinen _userService aufrufen und meine user_list auffüllen, aber vielleicht möchte ich noch ein paar Dinge damit tun. Wenn Sie sicherstellen möchten, dass alles in Großbuchstaben ist, bin ich nicht ganz sicher, wie meine Daten durchkommen.

So wird die Verwendung von ngOnInit wesentlich einfacher.

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


}

Es macht es viel einfacher zu sehen, und deshalb rufe ich meine Funktion einfach in meiner Komponente auf, wenn ich initialisiere, anstatt Dig für eine andere Stelle zu suchen. Es ist wirklich nur ein weiteres Werkzeug, mit dem Sie es in Zukunft leichter lesen und verwenden können. Ich finde es auch sehr schlecht, Funktionsaufrufe in einen Konstruktor zu setzen!

81
Morgan G

OK, ist zunächst ngOnInit Teil von Angular Lifecycle, während constructor Teil von ES6 JavaScript-Klasse ist. Der Hauptunterschied beginnt also hier! ...

Schauen Sie sich das unten erstellte Diagramm an, das den Lebenszyklus von Angular zeigt.

 ngOnInit vs constructor

In Angular2 + verwenden wir constructor, um die DI(Dependency Injection) für uns zu erledigen, während in Angular 1 der Aufruf der String-Methode erfolgte und die Abhängigkeit geprüft wurde. 

Wie Sie im obigen Diagramm sehen, geschieht ngOnInit, nachdem der Konstruktor fertig ist und ngOnChnages und gefeuert wird, nachdem die Komponente für uns bereit ist. In dieser Phase kann jede Initialisierung erfolgen. Ein einfaches Beispiel fügt einen Dienst hinzu und initialisiert ihn bei init.

OK, ich teile auch einen Beispielcode für Sie, um zu sehen, wie wir ngOnInit und constructor im folgenden Code verwenden:

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

Der erste (Konstruktor) bezieht sich auf die Klasseninstanziierung und hat nichts mit Angular2 zu tun. Ich meine, ein Konstruktor kann für jede Klasse verwendet werden. Sie können eine Initialisierungsverarbeitung für die neu erstellte Instanz einfügen.

Der zweite entspricht einem Lebenszyklushaken aus Angular2-Komponenten:

Zitiert von der offiziellen Website von angle:

  • ngOnChanges wird aufgerufen, wenn sich ein Eingabe- oder Ausgabebindungswert ändert
  • ngOnInit wird nach der ersten ngOnChanges aufgerufen

Sie sollten also ngOnInit verwenden, wenn die Initialisierungsverarbeitung auf Bindungen der Komponente angewiesen ist (z. B. mit @Input definierte Komponentenparameter).

44

Kurze und einfache Antwort wäre,

Constructor: constructor ist ein default method, der ausgeführt wird (durch Deafult), wenn eine Komponente erstellt wird. Wenn Sie an instance einer Klasse erstellen, wird zu diesem Zeitpunkt auch constructor(default method) aufgerufen. Mit anderen Worten, wenn Komponente aufgerufen wird, wird constructed or/and an instance is created constructor(default method) aufgerufen und der darin enthaltene relevante Code aufgerufen. Grundsätzlich und allgemein in Angular2 wurden Elemente wie services eingefügt, wenn eine Komponente für die weitere Verwendung erstellt wird.

OnInit: ngOnInit ist der Lebenszyklus-Hook der Komponente, der nach constructor(default method) zuerst ausgeführt wird, wenn die Komponente initialisiert wird. 

Ihr Konstruktor wird also zuerst aufgerufen und Oninit wird später nach der Konstruktormethode aufgerufen.

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

Ressourcen: Lebenszyklushaken

Sie können diese small Demo überprüfen, die die Implementierung beider Dinge zeigt.

27
micronyks

Ich werde nur eine wichtige Sache hinzufügen, die in den obigen Erklärungen übersprungen wurde und erklärt, wann ngOnInit verwenden muss.

Wenn Sie das DOM der Komponente über z. ViewChildren, ContentChildren oder ElementRef, Ihre nativen Elemente sind während der Konstruktorphase nicht verfügbar.

Da jedoch ngOnInit ausgeführt wird, nachdem die Komponente erstellt und die Prüfungen (ngOnChanges) aufgerufen wurden, können Sie an dieser Stelle auf das DOM zugreifen.

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
  }
}
24
Miroslav Jonas

Um dies zu testen, habe ich diesen Code geschrieben und aus dem NativeScript Tutorial entlehnt:

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

}

Konsolenausgabe

JS: *** User class constructor property ***  
JS: *** User class constructor constructor ***  
JS: *** Login Component Constructor ***  
JS: *** User class constructor ngOnInit ***  
JS: *** Login Component ngOnInit ***  
16
jmb-mage

Der Hauptunterschied zwischen Konstruktor und ngOnInit besteht darin, dass ngOnInitLebenszyklus-Hook ist und nach Konstruktor ausgeführt wird. Komponenten-interpolierte Vorlagen- und Eingabe-Anfangswerte sind im Konstruktor nicht verfügbar, jedoch in ngOnInit.

Der praktische Unterschied ist, wie ngOnInit die Struktur des Codes beeinflusst. Die meisten Initialisierungscodes können nach ngOnInit - verschoben werden, sofern dadurch keine Race-Bedingungen erstellt werden.

Konstruktor-Antimuster

Eine beträchtliche Menge an Initialisierungscode macht es schwierig, die Konstruktormethode zu erweitern, zu lesen und zu testen.

Ein übliches Rezept zum Trennen der Initialisierungslogik vom Klassenkonstruktor ist das Verschieben in eine andere Methode wie init:

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

  init() {...}
}

ngOnInit kann diesen Zweck in Komponenten und Anweisungen erfüllen:

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

ngOnInit() {
  // rest of initialization code
}

Abhängigkeitsspritze

Die primäre Rolle von Klassenkonstruktoren in Angular ist die Abhängigkeitsinjektion. Konstruktoren werden auch für DI-Annotationen in TypeScript verwendet. Fast alle Abhängigkeiten werden der Klasseninstanz als Eigenschaften zugewiesen.

Ein durchschnittlicher Konstruktor für Komponenten/Anweisungen ist bereits groß genug, da er aufgrund von Abhängigkeiten eine mehrzeilige Signatur aufweisen kann. Dies trägt dazu bei, dass eine unnötige Initialisierungslogik in den Konstruktorkörper eingefügt wird.

Asynchrone Initialisierung

Konstruktor für asynchrone Initialisierung kann oft als Antipattern und als Geruch angesehen werden, da die Klasseninstanziierung beendet wird, bevor die asynchrone Routine ausgeführt wird. Dies kann zu Race-Bedingungen führen. Wenn dies nicht der Fall ist, sind ngOnInit und andere Lebenszyklus-Hooks dafür bessere Orte, insbesondere, weil sie von der async-Syntax profitieren können:

constructor(
  public foo: Foo,
  public errorHandler: ErrorHandler
) {}

async ngOnInit() {
  try {
    await this.foo.getBar();
    await this.foo.getBazThatDependsOnBar();
  } catch (err) {
    this.errorHandler.handleError(err);
  }
}

Wenn Race-Bedingungen vorliegen (einschließlich der Bedingung, dass eine Komponente bei einem Initialisierungsfehler nicht angezeigt werden sollte), sollte eine asynchrone Initialisierungsroutine vor der Instantiierung der Komponenten stattfinden und zur übergeordneten Komponente, zum Router-Guard usw. verschoben werden.

Unit-Tests

ngOnInit ist flexibler als ein Konstruktor und bietet einige Vorteile für Komponententests, die ausführlich in diese Antwort erläutert werden.

In Anbetracht dessen, dass ngOnInit bei Komponententests in Komponententests nicht automatisch aufgerufen wird, können Methoden, die in ngOnInit aufgerufen werden, nach der Instanziierung von Komponenten ausspioniert oder gemustert werden.

In Ausnahmefällen kann ngOnInit vollständig überbrückt werden, um andere Komponenteneinheiten zu isolieren (z. B. einige Vorlagenlogik).

Erbe

Untergeordnete Klassen können Konstruktoren nur erweitern, nicht ersetzen.

Da this nicht vor super() referenziert werden kann, sind die Initialisierungsvorgaben eingeschränkt.

In Anbetracht dessen, dass die Angular-Komponente oder -Direktive ngOnInit für zeitunabhängige Initialisierungslogik verwendet, können untergeordnete Klassen auswählen, ob super.ngOnInit() aufgerufen wird und wann:

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

Dies ist mit dem Konstruktor alleine nicht zu implementieren.

14
estus

Wie viele andere Sprachen können Sie Variablen auf Klassenebene, im Konstruktor oder in einer Methode initialisieren. Es ist Sache des Entwicklers, zu entscheiden, was in seinem speziellen Fall am besten ist. Nachfolgend finden Sie eine Liste mit Best Practices für die Entscheidungsfindung.

Variablen auf Klassenebene 

In der Regel werden Sie hier alle Variablen deklarieren, die in der restlichen Komponente verwendet werden. Sie können sie initialisieren, wenn der Wert nicht von etwas anderem abhängt, oder das Schlüsselwort const zum Erstellen von Konstanten verwenden, wenn sich diese nicht ändern.

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

Konstrukteur

Normalerweise empfiehlt es sich, im Konstruktor nichts zu tun und nur für Klassen zu verwenden, die eingefügt werden sollen. In der Regel sollte Ihr Konstruktor so aussehen:

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

dadurch werden die Klassenebenenvariablen automatisch erstellt, sodass Sie auf customService.myMethod() zugreifen können, ohne dass Sie dies manuell vornehmen müssen.

NgOnInit

NgOnit ist ein Lebenszyklus-Hook, der vom Angular 2-Framework bereitgestellt wird. Ihre Komponente muss OnInit implementieren, um sie verwenden zu können. Dieser Lebenszyklus-Hook wird aufgerufen, nachdem der Konstruktor aufgerufen wurde und alle Variablen initialisiert wurden. Der Großteil Ihrer Initialisierung sollte hier hingehen. Sie haben die Gewissheit, dass Angular Ihre Komponente korrekt initialisiert hat, und Sie können damit beginnen, die erforderliche Logik in OnInit auszuführen, anstatt Dinge zu tun, wenn Ihre Komponente nicht ordnungsgemäß geladen wurde. 

Hier ist ein Bild, das die Reihenfolge des Aufrufs beschreibt:

 enter image description here

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

TLDR 

Wenn Sie das Angular 2-Framework verwenden und mit bestimmten Lebenszyklusereignissen interagieren müssen, verwenden Sie die vom Framework dafür bereitgestellten Methoden, um Probleme zu vermeiden.

13
Eduardo Dennis

Die obigen Antworten beantworten diesen Aspekt der ursprünglichen Frage nicht wirklich: Was ist ein Lebenszyklushaken? Ich habe eine Weile gebraucht, um zu verstehen, was das bedeutet, bis ich so darüber nachgedacht habe.

1) Angenommen, Ihre Komponente ist ein Mensch. Menschen haben ein Leben, das viele Lebensabschnitte umfasst, und dann verfallen wir. 

2) Unsere menschliche Komponente könnte das folgende Lebenszyklus-Skript haben: Geboren, Baby, Grundschule, junger Erwachsener, Erwachsener mittleren Alters, älterer Erwachsener, tot, entsorgt.

3) Angenommen, Sie möchten eine Funktion zum Erstellen von Kindern haben. Um zu verhindern, dass dies kompliziert und eher humorvoll wird, möchten Sie, dass Ihre Funktion nur im Stadium des jungen Erwachsenen des menschlichen Komponentenlebens aufgerufen wird. Sie entwickeln also eine Komponente, die nur aktiv ist, wenn sich die übergeordnete Komponente im Stadium des jungen Erwachsenen befindet. Hooks helfen Ihnen dabei, indem Sie diesen Lebensabschnitt signalisieren und Ihre Komponente darauf einwirken lassen.

Lustige Sachen. Wenn Sie Ihre Phantasie tatsächlich dazu verwenden, so etwas zu codieren, wird es kompliziert und lustig.

11
Preston

Derconstructorist eine Methode in JavaScript und wird als ein Feature der Klasse in es6 betrachtet. Wenn die Klasse instanziiert wird, führt sie den Konstruktor sofort aus, unabhängig davon, ob sie im Angular-Framework verwendet wird oder nicht von JavaScript-Engine aufgerufen und Angular hat keine Kontrolle darüber. 

import {Component} from '@angular/core';
@Component({})
class CONSTRUCTORTEST {

//This is called by Javascript not the Angular.
     constructor(){
        console.log("view constructor initialised");
     }
}

Die "ConstructorTest" -Klasse wird unten instanziiert. Sie ruft intern den -Konstruktor auf (All dies geschieht durch JavaScript (es6) und kein Angular).

new CONSTRUCTORTEST();

Deshalb gibt es in Angular.ngOnInit den RendererngOnInitlifecycle, wenn Angular die Initialisierung der Komponente abgeschlossen hat.

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

Zuerst instanziieren wir die Klasse wie folgt, die unmittelbar zur Ausführung der Konstruktormethode führt.

let instance = new NGONINITTEST();

ngOnInit wird von Angular bei Bedarf wie folgt aufgerufen:

instance.ngOnInit();

Aber Sie fragen sich vielleicht, warum wir in Angular einen Konstruktor verwenden?

Die Antwort istDependencies injections. Wie bereits erwähnt, ruft der Konstruktor die JavaScript-Engine sofort auf, wenn die Klasse instanziiert wird (bevor ngOnInit von Angular aufgerufen wird), daher hilft TypeScript, den Typ der Abhängigkeiten zu ermitteln sind im Konstruktor definiert und geben Angular schließlich an, welche Art von Abhängigkeiten wir in dieser spezifischen Komponente verwenden möchten.

7
Negin

Zwei Dinge, die hier zu beachten sind:

  1. Der Konstruktor wird immer dann aufgerufen, wenn ein Objekt dieser Klasse erstellt wird. 
  2. ngOnInit wird aufgerufen, sobald die Komponente erstellt wurde. 

Beide haben unterschiedliche Verwendbarkeit.

7
UniCoder

Konstruktor: Die Konstruktormethode für eine ES6-Klasse (oder in diesem Fall TypeScript) ist ein Feature einer Klasse selbst und nicht ein Angular-Feature. Es liegt außerhalb des Einflussbereichs von Angular, wenn der Konstruktor aufgerufen wird. Dies bedeutet, dass es kein geeigneter Haken ist, um Sie darüber zu informieren, wann Angular die Initialisierung der Komponente abgeschlossen hat. Die JavaScript-Engine ruft den Konstruktor auf, nicht direkt Angular. Aus diesem Grund wurde der Lebenszyklus-Hook ngOnInit (und $ onInit in AngularJS) erstellt. Vor diesem Hintergrund gibt es ein geeignetes Szenario für die Verwendung des Konstruktors. In diesem Fall möchten wir die Abhängigkeitseinspritzung nutzen - im Wesentlichen für die "Verdrahtung" von Abhängigkeiten in der Komponente.

Da der Konstruktor von der JavaScript-Engine initialisiert wird und TypeScript es ermöglicht, Angular mitzuteilen, welche Abhängigkeiten wir einer bestimmten Eigenschaft zuordnen müssen.

ngOnInit gibt uns nur ein Signal, dass Angular die Initialisierung der Komponente abgeschlossen hat.

Diese Phase umfasst den ersten Durchgang bei der Änderungserkennung gegen die Eigenschaften, die wir möglicherweise an die Komponente selbst binden können, z. B. die Verwendung eines @Input () - Dekorators.

Aus diesem Grund sind die @Input () - Eigenschaften in ngOnInit verfügbar, im Konstruktor jedoch nicht definiert

4
Vishal Gulati

Beide Methoden haben unterschiedliche Ziele/Verantwortlichkeiten. Die Aufgabe des Konstruktors (der eine sprachgestützte Funktion ist) besteht darin, sicherzustellen, dass die Repräsentationsinvariante gilt. Andernfalls wird angegeben, dass die Instanz gültig ist, indem den Mitgliedern korrekte Werte angegeben werden. Es ist Sache des Entwicklers, zu entscheiden, was "richtig" bedeutet.

Die Aufgabe der Methode onInit () (die ein Winkelkonzept ist) besteht darin, Methodenaufrufe für ein korrektes Objekt (Darstellungsinvariante) zuzulassen. Jede Methode sollte wiederum sicherstellen, dass die Repräsentationsinvariante gilt, wenn die Methode beendet wird.

Der Konstruktor sollte verwendet werden, um 'korrekte' Objekte zu erstellen. Die onInit-Methode gibt Ihnen die Möglichkeit, Methodenaufrufe an einer genau definierten Instanz aufzurufen.

4

constructor () ist die Standardmethode im Komponentenlebenszyklus und wird für die Abhängigkeitsinjektion verwendet. Konstruktor ist eine TypeScript-Funktion.

ngOnInit () wird nach dem Konstruktor und ngOnInit nach dem ersten ngOnChanges aufgerufen.

d. h. Konstruktor () -> ngOnChanges () -> ngOnInit ()

wie oben erwähnt, wird ngOnChanges () aufgerufen, wenn sich ein Eingabe- oder Ausgabebindungswert ändert.

4
shajin cse

Konstruktor ist der erste, und es kommt manchmal vor, wenn @input -Daten null!

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

Beispiel für onInit:

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

Ich denke, dass onInit mit InitialComponents () in WinForm vergleichbar ist.

1
user1012506

Ich habe die Antwort gefunden und versucht, sie ins Englische zu übersetzen: Diese Frage ist auch in technischen Interviews noch aufgetaucht. In der Tat gibt es eine große Ähnlichkeit zwischen den beiden, aber es gibt auch einige Unterschiede.

  • Der Konstruktor ist Teil von ECMAScript. Andererseits ist ngOnInit () ein Begriff von eckig.

  • Wir können die Konstruktoren in allen Klassen aufrufen, auch wenn wir Angular nicht verwenden

  • LifeCycle: Der Konstruktor wird vor ngOnInt () aufgerufen

  • Im Konstruktor können wir keine HTML-Elemente aufrufen. In ngOnInit () ist dies jedoch möglich.

  • Generell Aufrufe von Diensten im ngOnInit () und nicht im Konstruktor

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

1
doudou

Eigentlich ngOnInit () aus zwei Hauptgründen:

1) Komplexe Initialisierungen kurz nach der Erstellung durchführen.

2) Um die Komponente einzurichten, nachdem Angular die Eingabeeigenschaften festgelegt hat.

Erfahrene Entwickler sind sich einig, dass Komponenten billig und sicher zu bauen sein sollten.

Misko Hevery, Angular Teamleiter, erklärt, warum Sie komplexe Konstruktorlogik vermeiden sollten.

Rufen Sie keine Daten in einem Komponentenkonstruktor ab. Sie sollten sich keine Sorgen machen, dass eine neue Komponente versucht, einen Remoteserver zu kontaktieren, wenn sie im Test erstellt wird oder bevor Sie sich entscheiden, ihn anzuzeigen. Konstruktoren sollten nicht mehr tun, als die anfänglichen lokalen Variablen auf einfache Werte zu setzen.

Ein ngOnInit () ist ein guter Ort, an dem eine Komponente ihre Anfangsdaten abrufen kann.

Denken Sie auch daran, dass die datengebundenen Eingabeeigenschaften einer Direktive erst nach der Erstellung festgelegt werden. Dies ist ein Problem, wenn Sie die Direktive basierend auf diesen Eigenschaften initialisieren müssen. Sie werden festgelegt, wenn ngOnInit () ausgeführt wird.

Die Methode ngOnChanges () ist Ihre erste Möglichkeit, auf diese Eigenschaften zuzugreifen. Angular ruft ngOnChanges () vor ngOnInit () und viele Male danach auf. NgOnInit () wird nur einmal aufgerufen.

Sie können sich darauf verlassen, dass Angular die Methode ngOnInit () kurz nach dem Erstellen der Komponente aufruft. Dort gehört die schwere Initialisierungslogik hin.

0

Konstruktor Ein Klassenkonstruktor in Angular wird hauptsächlich zum Einfügen von Abhängigkeiten verwendet. Angular ruft dieses Konstruktorinjektionsmuster auf, das hier ausführlich erläutert wird. Für detailliertere Einblicke in die Architektur können Sie Constructor Injection vs. Setter Injection von Miško Hevery lesen.

Die Verwendung eines Konstruktors ist jedoch nicht auf DI beschränkt. Die Router-Outlet-Direktive des @ angle/router-Moduls registriert sich selbst und seinen Standort (viewContainerRef) im Router-Ökosystem. Ich habe diesen Ansatz unter Hier erfahren Sie, wie Sie ViewContainerRef abrufen, bevor die @ViewChild-Abfrage ausgewertet wird.

Die übliche Praxis ist jedoch so wenig Logik wie möglich in Konstruktoren.

NgOnInit Wie wir oben erfahren haben, wenn Angular ngOnInit aufruft, wurde die Erstellung eines Komponenten-DOMs abgeschlossen und alle erforderlichen Abhängigkeiten über den Konstruktor injiziert und Eingabebindungen verarbeitet. Hier haben Sie also alle erforderlichen Informationen zur Verfügung, die es zu einem guten Ort für die Durchführung der Initialisierungslogik machen.

Es ist eine gängige Praxis, ngOnInit zur Durchführung der Initialisierungslogik zu verwenden, auch wenn diese Logik nicht von DI-, DOM- oder Eingabebindungen abhängt.

0
arun thakur

In den Angular Lebenszyklen

1) Winkeleinspritzventil erkennt Konstruktorparameter und instanziiert die Klasse.

2) Nächster Lebenszyklus des Winkelrufs

Angular Lifecycle Hooks

ngOnChanges -> Aufruf der Direktiven Parameterbindung.

ngOnInit -> Winkel-Rendering starten ...

Rufen Sie eine andere Methode mit dem Status des Winkellebenszyklus auf.

0

Die Variable constructor wird aufgerufen, wenn Angular die Komponente "instanziiert/konstruiert". Die Methode ngOnInit ist ein Hook, der den Initialisierungsteil des Komponentenlebenszyklus darstellt. Eine bewährte Methode ist, sie nur für Service-Injection) zu verwenden:

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

Selbst wenn es möglich ist, sollten Sie keine "Arbeit" im Inneren ausführen. Wenn Sie eine Aktion starten möchten, die bei der Komponente "Initialisierung" ausgeführt werden muss, verwenden Sie ngOnInit:

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

Darüber hinaus können Aktionen, die Eingabeeigenschaften betreffen und von einer übergeordneten Komponente stammen, nicht im Konstruktor ..__ ausgeführt werden. Sie sollten in der ngOnInit-Methode oder einem anderen Hook ..__ abgelegt werden für ein Element, das sich auf die Sicht bezieht (das DOM), zum Beispiel Viewchild-Elemente:

@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
veben

Konstruktor ist eine Funktion, die ausgeführt wird, wenn eine Komponente (oder eine andere Klasse) erstellt wird.

ngOnInit ist eine Funktion, die zu einer Methodengruppe für den Komponentenlebenszyklus gehört. Sie wird zu einem anderen Zeitpunkt unserer Komponente ausgeführt (daher Name Lifecycle). . Hier ist eine Liste von allen:

enter image description here Der Konstruktor wird vor jeder Lebenszyklusfunktion ausgeführt.

0

constructor() wird zur Abhängigkeitsinjektion verwendet.

ngOnInit(), ngOnChanges() und ngOnDestroy() etc. sind Lebenszyklusmethoden. ngOnChanges() ist der erste Aufruf vor ngOnInit(). Wenn sich der Wert einer gebundenen Eigenschaft ändert, wird er NICHT aufgerufen, wenn keine Änderung vorliegt. ngOnDestroy() wird aufgerufen, wenn die Komponente entfernt wird. Um es zu verwenden, muss OnDestroy von der Klasse implemented sein.

0
student