Solución:
los Constructor
es un método predeterminado de la clase que se ejecuta cuando se crea una instancia de la clase y asegura la inicialización adecuada de los campos en la clase y sus subclases. Angular, o mejor Dependency Injector (DI), analiza los parámetros del constructor y cuando crea una nueva instancia llamando new MyClass()
intenta encontrar proveedores que coincidan con los tipos de parámetros del constructor, los resuelve y los pasa al constructor como
new MyClass(someArg);
ngOnInit
es un gancho de ciclo de vida llamado por Angular para indicar que Angular ha terminado de crear el componente.
Tenemos que importar OnInit
así para usarlo (realmente implementando OnInit
no es obligatorio pero se considera una buena práctica):
import { Component, OnInit } from '@angular/core';
luego para hacer uso 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 la lógica de inicialización personalizada después de que se hayan inicializado las propiedades enlazadas a datos de su directiva. ngOnInit se llama inmediatamente después de que se hayan verificado las propiedades vinculadas a datos de la directiva por primera vez y antes de que se haya verificado cualquiera de sus elementos secundarios. Se invoca solo una vez cuando se crea una instancia de la directiva.
Mayoritariamente usamos ngOnInit
para toda la inicialización / declaración y evitar que las cosas funcionen en el constructor. El constructor solo debe usarse para inicializar miembros de la clase, pero no debe hacer un “trabajo” real.
Entonces deberías usar constructor()
para configurar Dependency Injection y no mucho más. ngOnInit () es un mejor lugar para “comenzar” – es donde / cuando se resuelven los enlaces de los componentes.
Para obtener más información, consulte aquí:
-
https://angular.io/api/core/OnInit
-
Constructor de componentes angulares Vs OnInit
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 la diferencia más importante relacionada con el proceso de inicialización del componente, que también muestra el uso diferente.
El proceso de arranque angular consta de dos etapas principales:
- construyendo el árbol de componentes
- ejecución de detección de cambios
El constructor del componente se llama cuando Angular construye un árbol de componentes. Todos los enlaces del 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 principal también está configurado para que pueda inyectar proveedores definidos en el componente principal, incluido el componente principal 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 inicia la detección de cambios, se construye el árbol de componentes y se han llamado a los constructores de todos los componentes del árbol. Además, los nodos de plantilla de cada componente se agregan al DOM. los @Input
El mecanismo 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 a partir de ngOnInit
.
Veamos un ejemplo rápido. Suponga que tiene la siguiente plantilla:
<my-app>
<child-comp [i]='prop'>
Entonces Angular comienza a arrancar la aplicación. Como dije, primero crea clases para cada componente. Entonces llama MyAppComponent
constructor. También crea un nodo DOM que es el elemento anfitrión del my-app
componente. Luego procede a crear un elemento anfitrión para el child-comp
y llamando ChildComponent
constructor. En esta etapa no está realmente preocupado por la i
enlace de entrada y cualquier enlace de ciclo de vida. Entonces, cuando este proceso termina, 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 el my-app
y llama ngOnInit
en la clase MyAppComponent. Luego procede a actualizar los enlaces para el child-comp
y llama ngOnInit
en la clase ChildComponent.
Puede hacer su lógica de inicialización en el constructor o en ngOnInit
dependiendo de lo que necesite disponible. Por ejemplo, el artículo Aquí se muestra 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:
- Todo lo que necesita saber sobre la detección de cambios en Angular
- $ Digest de Angular renace en la versión más nueva de Angular
- La mecánica de los enlaces de propiedades se actualiza en Angular
Creo que el mejor ejemplo sería el uso de 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 registrarlos 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 asegurarme de que todo esté en mayúsculas, no estoy del todo seguro de cómo llegan mis datos.
Por lo que hace que sea 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 simplemente llamo a mi función dentro de mi componente cuando inicializo en lugar de tener que buscarla en otro lugar. Realmente es solo otra herramienta que puede utilizar para facilitar su lectura y uso en el futuro. ¡También me parece una práctica muy mala poner llamadas a funciones dentro de un constructor!