Diferença entre Construtor e ngOnInit

Angular fornece gancho de ciclo de vida ngOnInit por padrão.

Por que o ngOnInit deve ser usado, se já tivermos um constructor ?

O Constructor é um método padrão da class que é executado quando a class é instanciada e garante a boot apropriada dos campos na class e suas subclasss. Angular ou melhor Dependency Injector (DI) analisa os parâmetros do construtor e quando cria uma nova instância chamando new MyClass() ele tenta encontrar provedores que correspondam aos tipos de parâmetros do construtor, os resolva e os transmita para o construtor como

 new MyClass(someArg); 

ngOnInit é um gancho de ciclo de vida chamado por Angular2 para indicar que o Angular está pronto para criar o componente.

Nós temos que importar o OnInit para usar assim (implementar o OnInit não é obrigatório, mas é uma boa prática):

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

então para usar o método do OnInit temos que implementar na class assim.

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

Implemente essa interface para executar a lógica de boot personalizada após as propriedades vinculadas a dados de sua diretiva terem sido inicializadas. O ngOnInit é chamado logo após as propriedades vinculadas a dados da diretiva terem sido verificadas pela primeira vez e antes de qualquer um de seus filhos ter sido verificado. É invocado apenas uma vez quando a diretiva é instanciada.

Principalmente usamos ngOnInit para toda a boot / declaração e evitamos coisas para trabalhar no construtor. O construtor só deve ser usado para inicializar os membros da class, mas não deve fazer “trabalho” real.

Então você deve usar o constructor() para configurar a Injeção de Dependência e não muito mais. ngOnInit () é melhor lugar para “iniciar” – é onde / quando as ligações dos componentes são resolvidos.

Para mais informações, consulte aqui:

Eu acho que o melhor exemplo seria usar serviços. Digamos que eu queira coletar dados do meu servidor quando meu componente for “Ativado”. Vamos dizer que eu também quero fazer algumas coisas adicionais aos dados depois que eu os obtenho do servidor, talvez eu receba um erro e queira registrá-lo de forma diferente.

É realmente fácil com o ngOnInit sobre um construtor, ele também limita quantas camadas de retorno de chamada eu preciso adicionar ao meu aplicativo.

Por exemplo:

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

com meu construtor eu poderia chamar meu _userService e preencher minha lista de usuários, mas talvez eu queira fazer algumas coisas extras com ele. Por exemplo, certifique-se de que tudo esteja em upper_case, não tenho certeza de como meus dados estão chegando.

Por isso, é muito mais fácil usar o ngOnInit.

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

Isso torna muito mais fácil de ver, e então eu apenas chamo minha function dentro do meu componente quando eu inicializo ao invés de ter que procurar por ele em outro lugar. Realmente é apenas mais uma ferramenta que você pode usar para facilitar a leitura e uso no futuro. Também acho que é uma prática muito ruim colocar chamadas de function dentro de um construtor!

O artigo A diferença essencial entre Construtor e ngOnInit em Angular explora a diferença de múltiplas outlook. Essa resposta fornece a explicação de diferença mais importante relacionada ao processo de boot do componente, que também mostra os diferentes usos.

O processo de bootstrap angular consiste nos dois principais estágios:

  • construindo tree de componentes
  • executando a detecção de alterações

O construtor do componente é chamado quando o Angular constrói a tree de componentes. Todos os ganchos do ciclo de vida são chamados como parte da execução da detecção de alterações.

Quando o Angular constrói a tree de componentes, o injetor do módulo raiz já está configurado para que você possa injetar quaisquer dependencies globais. Além disso, quando o Angular instancia uma class de componente filho, o injetor para o componente pai também já está configurado para que você possa injetar provedores definidos no componente pai, incluindo o próprio componente pai. Os construtores de componentes são o único método que é chamado no contexto do injetor, portanto, se você precisar de alguma dependência, esse é o único local para obter essas dependencies.

Quando Angular inicia a detecção de mudança, a tree de componentes é construída e os construtores de todos os componentes da tree são chamados. Além disso, os nós de modelo de cada componente são adicionados ao DOM. O mecanismo de comunicação @Input é processado durante a detecção de alterações, portanto, você não pode esperar ter as propriedades disponíveis no construtor. Ele estará disponível após ngOnInit .

Vamos ver um exemplo rápido. Suponha que você tenha o seguinte modelo:

   

Então Angular inicia o bootstrap do aplicativo. Como eu disse, primeiro cria classs para cada componente. Por isso, chama o construtor MyAppComponent . Ele também cria um nó DOM que é o elemento host do componente my-app . Em seguida, ele continua criando um elemento host para o construtor child-comp e chamando ChildComponent . Neste estágio, não está realmente preocupado com a binding de input i e com os ganchos do ciclo de vida. Então, quando esse processo é concluído, o Angular acaba com a seguinte tree de visualizações de componentes:

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

Só então executa a detecção de alterações e atualiza as ligações para o my-app e chama ngOnInit na class MyAppComponent. Em seguida, ele continua atualizando as ligações para o child-comp e chama ngOnInit na class ChildComponent.

Você pode fazer sua lógica de boot no construtor ou ngOnInit dependendo do que você precisa disponível. Por exemplo, o artigo Aqui está como obter ViewContainerRef antes que a consulta @ViewChild seja avaliada mostre que tipo de lógica de boot pode ser necessário para ser executado no construtor.

Aqui estão alguns artigos que ajudarão você a entender melhor o tópico:

  • Tudo o que você precisa saber sobre a detecção de alterações no Angular
  • O $ digular do Angular renasce na versão mais recente do Angular
  • A mecânica das ligações de propriedade é atualizada no Angular

O primeiro (construtor) está relacionado à instanciação da class e não tem nada a ver com o Angular2. Quero dizer, um construtor pode ser usado em qualquer class. Você pode colocar nele algum processamento de boot para a instância recém-criada.

O segundo corresponde a um gancho de ciclo de vida de componentes do Angular2:

Citado no site oficial do angular:

  • ngOnChanges é chamado quando um valor de binding de input ou saída é alterado
  • ngOnInit é chamado após o primeiro ngOnChanges

Portanto, você deve usar ngOnInit se o processamento de boot depender de ligações do componente (por exemplo, parâmetros de componente definidos com @Input ), caso contrário, o construtor será suficiente …

OK, primeiro de tudo ngOnInit faz parte do ciclo de vida Angular , enquanto o constructor é parte da class JavaScript ES6 , então a grande diferença começa a partir daqui! …

Veja o gráfico abaixo que criei, que mostra o ciclo de vida do Angular.

ngOnInit vs construtor

Em Angular2 + utilizamos constructor para fazer a DI(Dependency Injection) para nós, enquanto em Angular 1 estava acontecendo através de chamada ao método String e verificando qual dependência foi injetada.

Como você vê no diagrama acima, ngOnInit está acontecendo depois que o construtor está pronto e ngOnChnages e é triggersdo depois que o componente estiver pronto para nós. Toda a boot pode acontecer neste estágio, uma simples amostra está injetando um serviço e inicializa no init.

OK, eu também compartilho um código de exemplo para você olhar, veja como usamos ngOnInit e constructor no código abaixo:

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

App is running!

`, styles: ['h1 { font-weight: normal; }'] }) class ExampleComponent implements OnInit { constructor(private router: Router) {} //Dependency injection in the constructor // ngOnInit, get called after Component initialised! ngOnInit() { console.log('Component initialised!'); } }

Resposta curta e simples seria,

Constructor : constructor é um default method executado ( por deafult ) quando o componente está sendo construído. Quando você cria an instance de uma class que também constructor(default method) tempo constructor(default method) seria chamado. Em outras palavras, quando o componente está sendo constructed or/and an instance is created constructor(default method) é chamado e o código relevante escrito dentro é chamado. Basicamente e geralmente em Angular2 , costumava injetar coisas como services quando o componente está sendo construído para uso posterior.

OnInit : ngOnInit é o gancho de ciclo de vida do componente que é executado primeiro após o constructor(default method) quando o componente está sendo inicializado.

Então, seu construtor será chamado primeiro e Oninit será chamado depois do método construtor.

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

Você pode conferir esta pequena demonstração que mostra a implementação das duas coisas.

Para testar isso, eu escrevi este código, pegando emprestado do Tutorial do 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; } } 

Saída do console

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

As respostas acima não respondem realmente a esse aspecto da pergunta original: o que é um gancho do ciclo de vida? Levei um tempo para entender o que isso significa até que pensei nisso dessa maneira.

1) Diga que seu componente é humano. Os seres humanos têm vidas que incluem muitos estágios de vida e então expiramos.

2) Nosso componente humano pode ter o seguinte roteiro de ciclo de vida: Nascido, Bebê, Escola de Ensino Fundamental, Adulto Jovem, Adulto de Idade Média, Adulto Sênior, Morto, Descartado de.

3) Digamos que você queira ter uma function para criar filhos. Para evitar que isso seja complicado, e bem humorado, você quer que sua function só seja chamada durante o estágio do Jovem Adulto da vida do componente humano. Assim, você desenvolve um componente que está ativo somente quando o componente pai está no estágio Adulto Jovem. Ganchos ajudam você a fazer isso sinalizando aquele estágio da vida e deixando seu componente agir sobre ele.

Coisas divertidas. Se você deixar sua imaginação ir para realmente codificar algo como isto, fica complicado, e engraçado.

Como muitas outras linguagens, você pode inicializar variables ​​no nível de class, no construtor ou em um método. Cabe ao desenvolvedor decidir o que há de melhor em seu caso particular. Mas abaixo estão uma lista das melhores práticas quando se trata de decidir.

Variáveis ​​de nível de class

Normalmente, você declarará todas as variables ​​aqui que serão usadas no restante de seu componente. Você pode inicializá-los se o valor não depender de mais nada, ou usar a palavra-chave const para criar constantes se elas não forem alteradas.

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

Construtor

Normalmente, é uma boa prática não fazer nada no construtor e usá-lo apenas para classs que serão injetadas. Na maioria das vezes seu construtor deve ficar assim:

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

isso criará automaticamente as variables ​​de nível de class, portanto, você terá access a customService.myMethod() sem precisar fazer isso manualmente.

NgOnInit

O NgOnit é um gancho do ciclo de vida fornecido pela estrutura Angular 2. Seu componente deve implementar o OnInit para usá-lo. Esse gancho de ciclo de vida é chamado depois que o construtor é chamado e todas as variables ​​são inicializadas. A maior parte da sua boot deve ser feita aqui. Você terá a certeza de que o Angular inicializou seu componente corretamente e pode começar a fazer qualquer lógica que precisar no OnInit versus fazer as coisas quando o componente não tiver terminado de carregar corretamente.

Aqui está uma imagem detalhando a ordem do que é chamado:

insira a descrição da imagem aqui

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

TLDR

Se você estiver usando o framework Angular 2 e precisar interagir com determinados events do ciclo de vida, use os methods fornecidos pela estrutura para evitar problemas.

A principal diferença entre o construtor e o ngOnInit é que ngOnInit é o gancho do ciclo de vida e é executado após o construtor. O modelo interpolado de componente e os valores iniciais de input não estão disponíveis no construtor, mas estão disponíveis em ngOnInit .

A diferença prática é como o ngOnInit afeta como o código é estruturado. A maioria dos códigos de boot pode ser movida para ngOnInitdesde que isso não crie condições de corrida .

Antipadrão de construtor

Uma quantidade substancial de código de boot dificulta a extensão, leitura e teste do método construtor.

Uma receita usual para separar a lógica de boot do construtor de class é movê-lo para outro método como o init :

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

ngOnInit pode servir este propósito em componentes e diretivas:

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

dependency injection

A principal function dos construtores de class no Angular é a injeção de dependência. Construtores também são usados ​​para anotação DI no TypeScript. Quase todas as dependencies são atribuídas como propriedades à instância de class.

O construtor médio de componente / diretiva já é grande o suficiente porque pode ter assinatura de múltiplas linhas devido a dependencies, colocando a lógica de boot desnecessária no corpo do construtor para o antipadrão.

Inicialização assíncrona

O construtor de boot asynchronous geralmente pode ser considerado antipadrão e ter um cheiro, pois a instanciação de class é concluída antes que a rotina assíncrona o faça, e isso pode criar condições de corrida. Se não for o caso, ngOnInit e outros ganchos do ciclo de vida são locais melhores para isso, particularmente porque eles podem se beneficiar da syntax async :

 constructor( public foo: Foo, public errorHandler: ErrorHandler ) {} async ngOnInit() { try { await this.foo.getBar(); await this.foo.getBazThatDependsOnBar(); } catch (err) { this.errorHandler.handleError(err); } } 

Se houver condições de corrida (incluindo aquela em que um componente não deve aparecer no erro de boot), a rotina de boot assíncrona deve ocorrer antes da instanciação do componente e ser movida para o componente pai, o roteador, etc.

Teste unitário

ngOnInit é mais flexível que um construtor e fornece alguns benefícios para o teste de unidade que são explicados detalhadamente nesta resposta .

Considerando que o ngOnInit não é chamado automaticamente na compilation de componentes em testes de unidade, os methods que são chamados em ngOnInit podem ser ngOnInit ou ridicularizados após a instanciação do componente.

Em casos excepcionais, ngOnInit pode ser totalmente stubbed para fornecer isolamento para outras unidades componentes (por exemplo, alguma lógica de modelo).

Herança

As classs filhas só podem aumentar os construtores, não substituí-los.

Como this não pode ser referido antes de super() , isso coloca restrições na precedência de boot.

Considerando que o componente ou diretiva Angular usa ngOnInit para lógica de boot insensível ao tempo, as classs super.ngOnInit() podem escolher se super.ngOnInit() é chamado e quando:

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

Isso seria impossível de implementar apenas com o construtor.

Vou apenas adicionar uma coisa importante que foi ignorada nas explicações acima e explica quando você deve usar ngOnInit .

Se você estiver fazendo alguma manipulação do DOM do componente, por exemplo, ViewChildren , ContentChildren ou ElementRef , seus elementos nativos não estarão disponíveis durante a fase do construtor.

No entanto, como o ngOnInit acontece assim que o componente é criado e as verificações ( ngOnChanges ) são chamadas, você pode acessar o DOM neste momento.

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

Angular 2 Construtores: –

  1. O construtor é um método padrão executado quando o componente está sendo construído.
  2. O construtor é um recurso de datilografia e é usado apenas para instanciações de classs e nada a ver com o Angular 2.
  3. O construtor chamado pela primeira vez antes do ngOnInit ().

Angular 2 ngOnInit: –

  1. O evento ngOnInit é um método de evento de ciclo de vida Angular 2 que é chamado após o primeiro ngOnChanges e o método ngOnInit é usado para parâmetros definidos com @Input, caso contrário, o construtor está OK.

  2. O ngOnInit é chamado após o construtor e ngOnInit é chamado após o primeiro ngOnChanges.

  3. O ngOnChanges é chamado quando um valor de binding de input ou saída é alterado.

O diagrama a seguir explica o ciclo de mentira do Angular. A partir disso, você pode ter uma ideia sobre a ordem em que cada um é chamado.

insira a descrição da imagem aqui

O construtor é um método em JavaScript e é considerado como um recurso da class em es6. Quando a class é instanciada, ele imediatamente executa o construtor, seja ele usado na estrutura Angular ou não. Assim, ele é chamado pelo mecanismo JavaScript e Angular não tem controle sobre isso.

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

A class “ConstructorTest” é instanciada abaixo, portanto chama internamente o construtor (Tudo isso acontece por JavaScript (es6) no Angular).

 new CONSTRUCTORTEST(); 

É por isso que existe um gancho de ciclo de vida ngOnInit no Angular.ngOnInit é processado quando o Angular termina de inicializar o componente.

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

Primeiro, instanciamos a class como abaixo, o que acontece com as execuções imediatas do método construtor.

 let instance = new NGONINITTEST(); 

ngOnInit é chamado pelo Angular quando necessário, conforme abaixo:

 instance.ngOnInit(); 

Mas você pode perguntar por que estamos usando construtor em Angular?

A resposta é injeções de dependencies . Como é mencionado anteriormente, chamadas de construtor pelo mecanismo JavaScript imediatamente quando a class é instanciada (antes de chamar ngOnInit por Angular), então typescript nos ajuda a obter o tipo de dependencies definidas no construtor e finalmente informa Angular que tipo de dependencies queremos usar nesse componente específico.

Duas coisas para observar aqui:

  1. O construtor é chamado sempre que um object é criado dessa class.
  2. ngOnInit chamado assim que o componente é criado.

Ambos têm usabilidade diferente.

Ambos os methods têm diferentes objectives / responsabilidades. A tarefa do construtor (que é um recurso suportado por idioma) é certificar-se de que a invariante de representação seja válida. Caso contrário, afirmou para se certificar de que a instância é válida, dando valores corretos para os membros. Cabe ao desenvolvedor decidir o que significa “correto”.

A tarefa do método onInit () (que é um conceito angular) é permitir chamadas de método em um object correto (representação invariante). Cada método, por sua vez, deve certificar-se de que a invariante de representação é válida quando o método é finalizado.

O construtor deve ser usado para criar objects ‘corretos’, o método onInit lhe dá a oportunidade de invocar chamadas de método em uma instância bem definida.

Construtor: O método construtor em uma class ES6 (ou TypeScript, neste caso) é um recurso de uma class em si, em vez de um recurso Angular. Está fora do controle do Angular quando o construtor é invocado, o que significa que não é um gancho adequado para informar quando o Angular terminar de inicializar o componente. O mecanismo JavaScript chama o construtor, não diretamente Angular. É por isso que o gancho do ciclo de vida ngOnInit (e $ onInit no AngularJS) foi criado. Tendo isso em mente, há um cenário adequado para usar o construtor. É quando queremos utilizar a injeção de dependência – essencialmente para “conectar” as dependencies no componente.

Como o construtor é inicializado pelo mecanismo JavaScript, e o TypeScript nos permite informar ao Angular quais dependencies precisamos ser mapeadas em relação a uma propriedade específica.

O ngOnInit está puramente lá para nos dar um sinal de que o Angular terminou de inicializar o componente.

Essa fase inclui a primeira passagem em Detecção de Alterações em relação às propriedades que podemos vincular ao próprio componente – como o uso de um decorador @Input ().

Devido a isto, as propriedades @Input () estão disponíveis dentro de ngOnInit, porém são indefinidas dentro do construtor, por design

constructor () é o método padrão no ciclo de vida do componente e é usado para injeção de dependência. Construtor é um recurso de datilografia.

ngOnInit () é chamado após o construtor e ngOnInit é chamado após o primeiro ngOnChanges.

ie Construtor () -> ngOnChanges () -> ngOnInit ()

como mencionado acima, ngOnChanges () é chamado quando um valor de binding de input ou saída é alterado.

constructor() é usado para fazer a injeção de dependência.

ngOnInit() , ngOnChanges() e ngOnDestroy() etc. são methods do ciclo de vida. ngOnChanges() será o primeiro a ser chamado, antes de ngOnInit() , quando o valor de uma propriedade associada for alterado, NÃO será chamado se não houver alteração. ngOnDestroy() é chamado quando o componente é removido. Para usá-lo, o OnDestroy precisa ser implement pela class.

Nos ciclos de vida angulares

1) O injetor angular detecta o parâmetro do construtor (‘s) e instancia a class.

2) Próximo ciclo de vida de chamada angular

Ganchos de ciclo de vida angular

ngOnChanges -> Chamada na binding de parâmetros diretivos.

ngOnInit -> Iniciar renderização angular …

Chame outro método com o estado do ciclo de vida angular.