Diferencia entre Constructor y ngOnInit

Respuestas:

1112

El Constructores un método predeterminado de la clase que se ejecuta cuando se instancia la clase y garantiza la inicialización adecuada de los campos en la clase y sus subclases. El Inyector de dependencia (DI) angular, o mejor, analiza los parámetros del constructor y cuando crea una nueva instancia al llamarla new MyClass(), intenta encontrar proveedores que coincidan con los tipos de los parámetros del constructor, los resuelve y los pasa al constructor como

new MyClass(someArg);

ngOnInit es un enlace de ciclo de vida llamado por Angular para indicar que Angular ha terminado de crear el componente.

Tenemos que importar de OnInitesta manera para usarlo (la implementación en realidad OnInitno es obligatoria pero se considera una buena práctica):

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

entonces para usar nos hace del método OnInit, tenemos que implementar la clase así:

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

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

Implemente esta interfaz para ejecutar una lógica de inicialización personalizada después de que se hayan inicializado las propiedades enlazadas a datos de su directiva. ngOnInit se llama justo después de que las propiedades vinculadas a datos de la directiva se hayan verificado por primera vez y antes de que se haya verificado cualquiera de sus elementos secundarios. Se invoca solo una vez cuando se instancia la directiva.

Principalmente usamos ngOnInitpara toda la inicialización / declaración y evitamos cosas para trabajar en el constructor. El constructor solo debe usarse para inicializar miembros de clase, pero no debe hacer "trabajo" real.

Por lo tanto, debe usar constructor()para configurar la inyección de dependencia y no mucho más. ngOnInit () es un mejor lugar para "comenzar": es donde / cuando se resuelven los enlaces de los componentes.

Para más información consulte aquí:

Pardeep Jain
fuente
62
Exactamente, la mayoría (o incluso todos) los lenguajes basados ​​en clases tienen constructores para garantizar un orden de inicialización adecuado, especialmente de las clases que extienden otras clases donde pueden surgir algunos problemas bastante difíciles, como los campos finales (no sé si TS los tiene) y similares. Los constructores no están relacionados con Angular2, son una característica de TypeScript. Angular llama a los ganchos del ciclo de vida después de que se llevó a cabo una inicialización o cuando ocurre un evento para permitir que el componente actúe en ciertas situaciones y para darle la oportunidad de realizar algunas tareas en el momento adecuado.
Günter Zöchbauer
13
Hay una cita de bloque en angular.io/docs/ts/latest/guide/server-communication.html que también explica esto: "Los componentes son más fáciles de probar y depurar cuando sus constructores son simples y todo el trabajo real (especialmente llamando a un servidor remoto) se maneja en un método separado ". - En este caso, ese método es ngOnInit ()
yoonjesung
3
es un enlace de ciclo de vida llamado por Angular2 para indicar que Angular ha terminado de crear el componente. Eso no es exactamente eso. señala que ha inicializado los enlaces. El componente se creó anteriormente. Ver mi respuesta
Max Koretskyi
22
Al igual que con todas las "mejores prácticas", creo que sería una buena idea explicar también por qué no debería estar haciendo "trabajo" en el constructor. Este artículo del líder del equipo de Angular es denso pero puede ayudar: misko.hevery.com/code-reviewers-guide/… Además, se debe dar menos importancia a los encantamientos necesarios para implementar OnInit (esto es fácil de encontrar) y más sobre El hecho crítico de que los enlaces de datos no están disponibles en el constructor.
Reikim
2
Si el modo estricto es cierto en tsconfig.jsonarchivos como "strict": true, entonces usted tiene que inicializar los miembros de la clase en el constructor, no en ngOnitcomo FormGroup.
Rohit Sharma
174

El artículo La diferencia esencial entre Constructor y ngOnInit en Angular explora la diferencia desde múltiples perspectivas. Esta respuesta proporciona la explicación de diferencia más importante relacionada con el proceso de inicialización de componentes, que también muestra la diferencia en el uso.

El proceso de arranque angular consta de dos etapas principales:

  • construyendo árbol de componentes
  • detección de cambios en ejecución

Se llama al constructor del componente cuando Angular construye el árbol de componentes. Todos los ganchos de ciclo de vida se llaman como parte de la detección de cambios en ejecución.

Cuando Angular construye el árbol de componentes, el inyector del módulo raíz ya está configurado para que pueda inyectar cualquier dependencia global. Además, cuando Angular crea una instancia de una clase de componente secundario, el inyector para el componente primario también ya está configurado para que pueda inyectar proveedores definidos en el componente primario, incluido el componente primario en sí. Los constructores de componentes son el único método que se llama en el contexto del inyector, por lo que si necesita alguna dependencia, ese es el único lugar para obtener esas dependencias.

Cuando Angular comienza la detección de cambios, se construye el árbol de componentes y se llama a los constructores de todos los componentes del árbol. Además, los nodos de plantilla de cada componente se agregan al DOM. El @Inputmecanismo de comunicación se procesa durante la detección de cambios, por lo que no puede esperar tener las propiedades disponibles en el constructor. Estará disponible el después ngOnInit.

Veamos un ejemplo rápido. Supongamos que tiene la siguiente plantilla:

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

Entonces Angular comienza a iniciar la aplicación. Como dije, primero crea clases para cada componente. Entonces se llama MyAppComponentconstructor. También crea un nodo DOM que es el elemento host del my-appcomponente. Luego se procede a crear un elemento host para el constructor child-compy llamar ChildComponent. En esta etapa, no está realmente preocupado por el ienlace de entrada y los ganchos de ciclo de vida. Entonces, cuando este proceso finaliza, Angular termina con el siguiente árbol de vistas de componentes:

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

Solo entonces ejecuta la detección de cambios y actualiza los enlaces para las my-appllamadas y ngOnIniten la clase MyAppComponent. Luego se procede a actualizar los enlaces para child-compy llama ngOnInita la clase ChildComponent.

Puede hacer su lógica de inicialización en cualquier constructor o en ngOnInitfunción de lo que necesite disponible. Por ejemplo, el artículo Aquí es cómo obtener ViewContainerRef antes de que se evalúe la consulta @ViewChild muestra qué tipo de lógica de inicialización se puede requerir que se realice en el constructor.

Aquí hay algunos artículos que lo ayudarán a comprender mejor el tema:

Max Koretskyi
fuente
33
Esta debería ser la respuesta aceptada. en realidad explica el POR QUÉ en lugar de repetir mantras y declarar the constructor should only be used to inject dependencies.
Stavm
1
@ yannick1976, gracias! Echa un vistazo a los artículos de referencia
Max Koretskyi
@flobacca, ¿puedes reformular la pregunta? Es difícil entender lo que estás preguntando
Max Koretskyi
Por favor corrígeme si estoy equivocado. Comprendí que el árbol de componentes se construye primero y luego cambia el proceso de detección. Primero escribió que se llama al constructor AppComponent (junto con las dependencias resueltas), luego se llama al constructor ChildComponent (junto con las dependencias), luego los enlaces de entrada para AppComponent y luego se llama a OnInit. Pero mi preocupación es que si agrego ganchos de ciclo de vida a ambos componentes, el flujo es AppComponentConstructor - -> AppComponentOnInit - → ChildComponentConstructor - → ChildComponentOnInit Por qué se llama a AppComponentOnInit antes de ChildComponentConstructor
user2485435
1
@MaxKoretskyiakaWizard tenías razón. He cometido algún error en la configuración de mi aplicación. Funciona según lo descrito por usted. angular-c7zjsx.stackblitz.io
user2485435
96

Creo que el mejor ejemplo sería usar servicios. Digamos que quiero obtener datos de mi servidor cuando mi componente se 'Activa'. Digamos que también quiero hacer algunas cosas adicionales a los datos después de obtenerlos del servidor, tal vez obtengo un error y quiero registrarlo de manera diferente.

Es realmente fácil con ngOnInit sobre un constructor, también limita la cantidad de capas de devolución de llamada que necesito agregar a mi aplicación.

Por ejemplo:

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 mi constructor podría simplemente llamar a mi _userService y completar mi user_list, pero tal vez quiera hacer algunas cosas adicionales con él. Como asegurarse de que todo esté en mayúsculas, no estoy completamente seguro de cómo se transmiten mis datos.

Por lo tanto, es mucho más fácil usar 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();
    };


}

Hace que sea mucho más fácil de ver, por lo que solo llamo a mi función dentro de mi componente cuando inicializo en lugar de tener que buscarlo en otro lugar. Realmente es solo otra herramienta que puede usar para facilitar su lectura y uso en el futuro. ¡También me parece una muy mala práctica poner llamadas a funciones dentro de un constructor!

Morgan G
fuente
Su ejemplo podría simplificarse si solo configura user_list en Observable. Angular2 tiene la tubería asíncrona, por lo que no habría ningún problema allí.
DarkNeuron
@ Morgan, solo para que yo aprenda algo pequeño aquí, ¿por qué primero creas una función getUsersy luego la insertas ngOnInit? ¿No es menos código simplemente escribirlo en ngOnInit? Me pregunto por qué la gente lo hace así. ¿Es para que pueda reutilizar el código si lo desea también? Gracias.
Alfa Bravo
31
Como se ve en la respuesta a continuación, esto no hace ninguna diferencia si está en el constructor. Esta no es una respuesta real al propósito.
Jimmy Kane
8
No veo cómo esto responde a la pregunta en absoluto. ¿Por qué no podrías simplemente poner el código en el constructor?
CodyBugstein
1
@ Morgan, ¿por qué no puedes simplemente hacerloconstructor(private _userService: UserService){ this.getUsers(); };
Ashley
82

OK, antes que nada ngOnInites parte del ciclo de vida de Angular , mientras que constructores parte de la clase ES6 JavaScript, ¡así que la gran diferencia comienza desde aquí! ...

Mire la tabla a continuación que creé que muestra el ciclo de vida de Angular.

ngOnInit vs constructor

En Angular2 + usamos constructorpara hacer el DI(Dependency Injection)para nosotros, mientras que en angular 1 que estaba ocurriendo a través de llamar al método de String y verificaciones que se inyectó la dependencia.

Como puede ver en el diagrama anterior, ngOnInitocurre después de que el constructor está listo ngOnChnagesy se despide después de que el componente está listo para nosotros. Toda la inicialización puede ocurrir en esta etapa, una muestra simple está inyectando un servicio y lo inicializa en init.

OK, también comparto un código de muestra para que lo veas, mira cómo usamos ngOnInity constructoren el siguiente código:

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!');
  }
}
Alireza
fuente
1
Gracias. Esta debería ser la mejor respuesta.
Don Dilanga
58

El primero (constructor) está relacionado con la instanciación de clase y no tiene nada que ver con Angular2. Quiero decir que un constructor se puede usar en cualquier clase. Puede incluir un proceso de inicialización para la instancia recién creada.

El segundo corresponde a un gancho de ciclo de vida de componentes Angular2:

Citado del sitio web oficial de angular:

  • ngOnChanges se llama cuando cambia un valor de enlace de entrada o salida
  • ngOnInit se llama después del primero ngOnChanges

Por lo tanto, debe usar ngOnInitsi el proceso de inicialización se basa en enlaces del componente (por ejemplo, los parámetros del componente definidos con @Input), de lo contrario, el constructor sería suficiente ...

Thierry Templier
fuente
49

Solo agregaré una cosa importante que se omitió en las explicaciones anteriores y explica cuándo DEBE usarla ngOnInit.

Si está manipulando el DOM del componente mediante, por ejemplo , ViewChildren , ContentChildren o ElementRef , sus elementos nativos no estarán disponibles durante la fase de construcción.

Sin embargo, dado que ngOnInitsucede una vez que se ha creado el componente y ngOnChangesse ha llamado a los controles ( ), puede acceder al DOM en este 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
  }
}
Miroslav Jonas
fuente
3
No En @ViewChildrenparticular, debe usar el ngAfterViewInitmétodo. Ver aquí: stackoverflow.com/questions/46314734/…
AsGoodAsItGets
1
Gracias, @AsGoodAsItGets por señalarlo. Ahora he mejorado la respuesta
Miroslav Jonas el
38

La respuesta corta y simple sería,

Constructor: constructores una ejecucióndefault method ( por defecto ) cuando el componente se está construyendo. Cuando creas an instanceuna clase, ese tiempo también constructor(default method)se llamará. En otras palabras, cuando constructed or/and an instance is created constructor(default method)se llama al componente y se llama al código relevante escrito dentro. Básicamente y en general Angular2solía inyectar cosas comoservices cuando el componente se está construyendo para su uso posterior.

OnInit: ngOnInit es el enlace del ciclo de vida del componente que se ejecuta primero después constructor(default method) que se inicializa el componente.

Entonces, su constructor se llamará primero y Oninit se llamará más tarde después del método del constructor.

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

Recursos: gancho LifeCycle

Puede consultar esta pequeña demostración que muestra la implementación de ambas cosas.

micronyks
fuente
55
Creo que "el constructor es algo que se ejecuta o llama cuando se inicializa el componente". es engañoso. El constructor es una característica de la clase, no del componente. Diría que la instancia de la clase solo se convierte en un componente después de que se llamó al constructor y Angular hizo su inicialización.
Günter Zöchbauer
Sí, cambió la declaración que puede verificar ahora.
micronyks
1
Hmm, en mi humilde opinión, sigue siendo el mismo "constructor (método predeterminado) es algo que se ejecuta o llama cuando se construye el componente". No solo se llama cuando se construye un componente, sino también para servicios o cuando new MyClass()se ejecuta un código similar . Creo que es engañoso decir que los constructores son sobre componentes, son sobre clases e instancias de inicialización de estas clases. Un componente resulta ser tal clase. De lo contrario, creo que es una buena respuesta.
Günter Zöchbauer
2
Si, absolutamente. Olvidé mencionar que cuando creas un objeto de una clase también constructorse llama ese tiempo . Pero esta respuesta ha sido escrita en contexto angular2. Para conocer la mejor respuesta, debe conocer los conceptos básicos de OOP. Aún así actualizaré la respuesta.
micronyks
@ GünterZöchbauer, no creo que sea una afirmación correcta que sea ​​una característica de la clase, no del componente . Desde la perspectiva del lenguaje de programación sí, esto es correcto. Pero puedo trabajar con éxito con componentes sin ningún tipo de gancho de ciclo de vida. Pero no puedo trabajar con un componente sin un constructor si necesito DI porque ese es el único lugar inyectable. Ver mi respuesta
Max Koretskyi
20

Al igual que muchos otros lenguajes, puede inicializar variables a nivel de clase, el constructor o un método. Depende del desarrollador decidir qué es lo mejor en su caso particular. Pero a continuación hay una lista de las mejores prácticas a la hora de decidir.

Variables a nivel de clase

Por lo general, declarará aquí todas sus variables que se utilizarán en el resto de su componente. Puede inicializarlos si el valor no depende de otra cosa, o usar la palabra clave const para crear constantes si no cambian.

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

Constructor

Normalmente, es una buena práctica no hacer nada en el constructor y simplemente usarlo para las clases que se inyectarán. La mayoría de las veces su constructor debería verse así:

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

esto creará automáticamente las variables de nivel de clase, por lo que tendrá acceso a customService.myMethod() sin tener que hacerlo manualmente.

NgOnInit

NgOnit es un enlace de ciclo de vida proporcionado por el marco Angular 2. Su componente debe implementarse OnInitpara poder usarlo. Este enlace de ciclo de vida se llama después de que se llama al constructor y se inicializan todas las variables. La mayor parte de su inicialización debería ir aquí. Tendrá la certeza de que Angular ha inicializado su componente correctamente y puede comenzar a hacer cualquier lógica que necesite enOnInit hacer cosas cuando su componente no haya terminado de cargarse correctamente.

Aquí hay una imagen que detalla el orden de lo que se llama:

ingrese la descripción de la imagen aquí

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

TLDR

Si está utilizando el marco Angular 2 y necesita interactuar con ciertos eventos del ciclo de vida, utilice los métodos proporcionados por el marco para evitar problemas.

Eduardo Dennis
fuente
19

Para probar esto, escribí este código, tomando prestado del Tutorial 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;
  }

}

Salida de la consola

JS: *** User class constructor property ***  
JS: *** User class constructor constructor ***  
JS: *** Login Component Constructor ***  
JS: *** User class constructor ngOnInit ***  
JS: *** Login Component ngOnInit ***  
abbaf33f
fuente
18

La principal diferencia entre constructor y ngOnInites que ngOnInites un enlace de ciclo de vida y se ejecuta después del constructor. La plantilla interpolada de componentes y los valores iniciales de entrada no están disponibles en el constructor, pero están disponibles enngOnInit .

La diferencia práctica es cómo ngOnInitafecta cómo se estructura el código. La mayoría del código de inicialización se puede mover a ngOnInit, siempre que esto no cree condiciones de carrera .

Constructor antipatrón

Una cantidad sustancial de código de inicialización hace que el método del constructor sea difícil de extender, leer y probar.

Una receta habitual para separar la lógica de inicialización del constructor de clases es moverla a otro método como init:

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

  init() {...}
}

ngOnInit puede cumplir este propósito en componentes y directivas:

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

ngOnInit() {
  // rest of initialization code
}

Inyección de dependencia

La función principal de los constructores de clases en Angular es la inyección de dependencia. Los constructores también se utilizan para la anotación DI en TypeScript. Casi todas las dependencias se asignan como propiedades a la instancia de clase.

El constructor promedio de componentes / directivas ya es lo suficientemente grande porque puede tener una firma multilínea debido a dependencias, por lo que poner una lógica de inicialización innecesaria en el cuerpo del constructor contribuye al antipatrón.

Inicialización asincrónica

El constructor de inicialización asincrónica a menudo se puede considerar antipatrón y tiene olor porque la instanciación de clase termina antes que la rutina asincrónica, y esto puede crear condiciones de carrera. Si no es el caso, ngOnInity otros ganchos de ciclo de vida son mejores lugares para esto, particularmente porque pueden beneficiarse de la asyncsintaxis:

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

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

Si hay condiciones de carrera (incluida la que un componente no debería aparecer en el error de inicialización), la rutina de inicialización asincrónica debe tener lugar antes de la creación de instancias del componente y pasar al componente principal, la protección del enrutador, etc.

Examen de la unidad

ngOnInites más flexible que un constructor y proporciona algunos beneficios para las pruebas unitarias que se explican en detalle en esta respuesta .

Teniendo en cuenta que ngOnInitno se llama automáticamente en la compilación de componentes en las pruebas unitarias, los métodos que se invocan ngOnInitse pueden espiar o burlar después de la creación de instancias de componentes.

En casos excepcionales ngOnInitse puede tropezar por completo para proporcionar aislamiento a otras unidades componentes (por ejemplo, alguna lógica de plantilla).

Herencia

Las clases secundarias solo pueden aumentar los constructores, no reemplazarlos.

Como thisno se puede referir antes super(), esto pone restricciones a la precedencia de inicialización.

Teniendo en cuenta que el componente angular o la directiva utiliza ngOnInitpara la lógica de inicialización insensible al tiempo, las clases secundarias pueden elegir si super.ngOnInit()se llama y cuándo:

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

Esto sería imposible de implementar solo con el constructor.

Estus Flask
fuente
12

Las respuestas anteriores realmente no responden a este aspecto de la pregunta original: ¿Qué es un gancho de ciclo de vida? Me tomó un tiempo entender lo que eso significa hasta que lo pensé de esta manera.

1) Digamos que tu componente es un humano. Los humanos tienen vidas que incluyen muchas etapas de la vida, y luego caducamos.

2) Nuestro componente humano podría tener el siguiente script de ciclo de vida: nacido, bebé, escuela primaria, adulto joven, adulto de mediana edad, adulto mayor, muerto, desechado.

3) Digamos que quieres tener una función para crear hijos. Para evitar que esto se complique, y sea bastante humorístico, desea que su función solo se llame durante la etapa de adulto joven de la vida del componente humano. Por lo tanto, desarrolla un componente que solo está activo cuando el componente principal está en la etapa Adulto joven. Los ganchos lo ayudan a hacerlo señalando esa etapa de la vida y dejando que su componente actúe sobre ella.

Cosas divertidas. Si dejas volar tu imaginación para codificar algo como esto, se vuelve complicado y divertido.

Preston
fuente
7

El constructor es un método en JavaScript y se considera como una característica de la clase en es6. Cuando se crea una instancia de la clase, inmediatamente ejecuta el constructor, ya sea que se use en el marco angular o no. Por lo tanto, el motor de JavaScript lo llama y Angular no tiene control sobre eso.

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

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

La clase "ConstructorTest" se instancia a continuación, por lo que internamente llama al constructor (todo esto sucede por JavaScript (es6) no Angular).

new CONSTRUCTORTEST();

Es por eso que hay un enlace de ciclo de vida ngOnInit en Angular.ngOnInit se muestra cuando Angular ha terminado de inicializar el componente.

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

Primero, instanciamos la clase como se muestra a continuación, que sucede con las ejecuciones inmediatas del método del constructor.

let instance = new NGONINITTEST();

Angular llama a ngOnInit cuando es necesario de la siguiente manera:

instance.ngOnInit();

Pero puede preguntar por qué estamos usando constructor en Angular?

La respuesta son las inyecciones de dependencias . Como se mencionó antes, el constructor llama por el motor de JavaScript inmediatamente cuando la clase se instancia (antes de llamar a ngOnInit por Angular), por lo que mecanografiado nos ayuda a obtener el tipo de dependencias que se definen en el constructor y finalmente dice Angular qué tipo de dependencias queremos usar en ese componente específico.

Negin
fuente
7

Dos cosas para observar aquí:

  1. Se llama al constructor cada vez que se crea un objeto de esa clase.
  2. Se llama a ngOnInit una vez que se crea el componente.

Ambos tienen usabilidad diferente.

UniCoder
fuente
5

constructor() es el método predeterminado en el ciclo de vida del Componente y se usa para la inyección de dependencia. Constructor es una característica de mecanografiado.

ngOnInit () se llama después del constructor y ngOnInit se llama después de los primeros ngOnChanges.

es decir:

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

como se mencionó anteriormente, ngOnChanges()se llama cuando cambia un valor de enlace de entrada o salida.

Shajin Chandran
fuente
4

Ambos métodos tienen diferentes objetivos / responsabilidades. La tarea del constructor (que es una característica compatible con el lenguaje) es asegurarse de que la representación sea invariable. De lo contrario, se asegurará de que la instancia sea válida al proporcionar los valores correctos a los miembros. Depende del desarrollador decidir qué significa "correcto".

La tarea del método onInit () (que es un concepto angular) es permitir invocaciones de métodos en un objeto correcto (representación invariable). Cada método debe a su vez asegurarse de que la representación invariable se mantenga cuando el método finalice.

El constructor debe usarse para crear objetos 'correctos', el método onInit le brinda la oportunidad de invocar llamadas a métodos en una instancia bien definida.

Bruno Ranschaert
fuente
4

Constructor: el método del constructor en una clase ES6 (o TypeScript en este caso) es una característica de una clase en sí misma, en lugar de una característica angular. Está fuera del control de Angular cuando se invoca el constructor, lo que significa que no es un enlace adecuado para hacerle saber cuando Angular ha terminado de inicializar el componente. El motor JavaScript llama al constructor, no Angular directamente. Es por eso que se creó el gancho del ciclo de vida ngOnInit (y $ onInit en AngularJS). Teniendo esto en cuenta, hay un escenario adecuado para usar el constructor. Esto es cuando queremos utilizar la inyección de dependencias, esencialmente para "conectar" dependencias en el componente.

Como el constructor es inicializado por el motor de JavaScript, y TypeScript nos permite decirle a Angular qué dependencias debemos asignar a una propiedad específica.

ngOnInit está ahí para darnos una señal de que Angular ha terminado de inicializar el componente.

Esta fase incluye el primer paso en la detección de cambios contra las propiedades que podemos unir al componente en sí, como el uso de un decorador @Input ().

Debido a esto, las propiedades @Input () están disponibles dentro de ngOnInit, sin embargo, no están definidas dentro del constructor, por diseño

Vishal Gulati
fuente
2

¡El constructor es el primero, y sucede a veces cuando los datos de @input son nulos! entonces usamos Constructor para declarar servicios y ngOnInit sucede después. Ejemplo para contrutor:

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

Ejemplo para onInit:

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

Creo que onInit es como InitialComponents () en winForm.

usuario1012506
fuente
1

En los ciclos de vida angulares

1) El inyector angular detecta los parámetros del constructor y crea una clase de instancia.

2) Siguiente ciclo de vida de la llamada angular

Ganchos de ciclo de vida angular

ngOnChanges -> Llamada en la directiva de enlace de parámetros.

ngOnInit -> Iniciar renderizado angular ...

Llame a otro método con estado de ciclo de vida angular.

Musulmán Shahsavan
fuente
1

El constructorse llama cuando Angular "instancia / construye" el componente. El ngOnInitmétodo es un enlace que representa la parte de inicialización del ciclo de vida del componente. Una buena práctica es usarlo solo para inyección de servicio :

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

Incluso si es posible, no debe hacer un "trabajo" en el interior. Si desea iniciar alguna acción que tiene que ocurrir en la "inicialización" del componente, use ngOnInit:

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

Además, las acciones que involucran propiedades de entrada , provenientes de un componente padre, no pueden realizarse en el constructor. Deben colocarse en ngOnInitmétodo u otro gancho. Es lo mismo para el elemento relacionado con la vista (DOM), por ejemplo, elementos 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
};
veben
fuente
0

constructor() se usa para hacer la inyección de dependencia.

ngOnInit(), ngOnChanges()y ngOnDestroy()etc. son métodos de ciclo de vida. ngOnChanges()será el primero en ser llamado, antes ngOnInit(), cuando cambie el valor de una propiedad vinculada, NO se llamará si no hay cambio. ngOnDestroy()se llama cuando se elimina el componente. Para usarlo, OnDestroydebe ser implementeditado por la clase.

xameeramir
fuente
1
De acuerdo, esto es corto y claro. Por ejemplo, constructor () es para agregar objetos de servicio, ngOnInit () es para manipular componentes con llamadas a funciones de servicio necesarias.
Steve
0

Encontré la respuesta y traté de traducirla al inglés: esta pregunta aún surgió, incluso en entrevistas técnicas. De hecho, hay un gran parecido entre los dos, pero también hay algunas diferencias.

  • El constructor es parte de ECMAScript. Por otro lado, ngOnInit () es una noción de angular.

  • Podemos llamar a los constructores en todas las clases incluso si no usamos Angular

  • LifeCycle: se llama al constructor antes que ngOnInt ()

  • En el constructor no podemos llamar elementos HTML. Sin embargo, en ngOnInit () podemos.

  • Generalmente, llamadas de servicios en ngOnInit () y no en el constructor

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

doudou
fuente
0

Constructor

La función de constructor viene con cada clase, los constructores no son específicos de Angular pero son conceptos derivados de diseños orientados a objetos. El constructor crea una instancia de la clase componente.

OnInit

La ngOnInitfunción es uno de los métodos de ciclo de vida de un componente angular. Los métodos de ciclo de vida (o ganchos) en componentes angulares le permiten ejecutar un código en diferentes etapas de la vida de un componente. A diferencia del método del constructor, el ngOnInitmétodo proviene de una interfaz angular ( OnInit) que el componente necesita implementar para usar este método. Se ngOnInitllama al método poco después de crear el componente.

Dic
fuente
0

El constructor se ejecuta cuando se instancia la clase. No tiene nada que ver con lo angular. Es la característica de Javascript y Angular no tiene el control sobre él.

NgOnInit es específico de Angular y se llama cuando Angular ha inicializado el componente con todas sus propiedades de entrada

Las propiedades @Input están disponibles bajo el enlace del ciclo de vida ngOnInit. Esto lo ayudará a hacer algunas cosas de inicialización, como obtener datos del servidor de fondo, etc. para mostrar en la vista

Las propiedades de @Input se muestran como indefinidas dentro del constructor

dasunse
fuente
-1

Constructor es una función ejecutada cuando se construye el componente (u otra clase).

ngOnInit es una función que pertenece a un grupo de métodos de ciclo de vida de componentes y se ejecutan en un momento diferente de nuestro componente (es por eso que se llama ciclo de vida). Aquí hay una lista de todos ellos:

ingrese la descripción de la imagen aquí El constructor se ejecutará antes de cualquier función del ciclo de vida.

Przemek Struciński
fuente