Diferença entre o Construtor e o ngOnInit

1075

Angular fornece gancho de ciclo de vida ngOnInitpor padrão.

Por que deve ngOnInitser usado, se já temos um constructor?

Haseena PA
fonte
11
hey, veja a minha resposta que explica a diferença do ponto de vista do funcionamento interno de Angular
Max Koretskyi
1
@MaximKoretskyi, seu link está morto.
Yash Capoor 16/01

Respostas:

1112

O Constructoré um método padrão da classe que é executada quando a classe é instanciada e garante a inicialização adequada dos campos na classe e suas subclasses. 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 dos parâmetros do construtor, os resolve e os passa para o construtor, como

new MyClass(someArg);

ngOnInit é um gancho de ciclo de vida chamado por Angular para indicar que Angular terminou de criar o componente.

Temos que importar OnInitassim para usá-lo (na verdade, implementar OnInitnão é obrigatório, mas é considerado uma boa prática):

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

então, para usar make do método OnInit, temos que implementar a classe 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 inicialização personalizada após a inicialização das propriedades vinculadas a dados da diretiva. O ngOnInit é chamado logo após as propriedades vinculadas aos 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.

Usamos principalmente ngOnInitpara toda a inicialização / declaração e evitamos coisas para trabalhar no construtor. O construtor deve ser usado apenas para inicializar os membros da classe, mas não deve fazer "trabalho" real.

Portanto, você deve constructor()configurar a Injeção de Dependências e não muito mais. ngOnInit () é o melhor lugar para "iniciar" - é onde / quando as ligações dos componentes são resolvidas.

Para mais informações, consulte aqui:

Pardeep Jain
fonte
62
Exatamente, a maioria (ou mesmo todas) as linguagens baseadas em classes têm contratadores para garantir uma ordem de inicialização adequada, especialmente de classes que estendem outras classes onde alguns problemas bastante difíceis podem surgir, como campos finais (não sei se o TS os possui) e similares. Os construtores não estão relacionados ao Angular2, são um recurso do TypeScript. Os ganchos do ciclo de vida são chamados pelo Angular após a inicialização de algum evento ou quando algum evento ocorre para permitir que o componente atue em determinadas situações e para dar a chance de executar algumas tarefas em momentos adequados.
Günter Zöchbauer 03/03
13
Há uma citação em bloco em angular.io/docs/ts/latest/guide/server-communication.html que também explica isso: "Os componentes são mais fáceis de testar e depurar quando seus construtores são simples e todo o trabalho real (especialmente chamando um servidor remoto) é tratado em um método separado ". - Nesse caso, esse método é o ngOnInit ()
yoonjesung
3
é um gancho de ciclo de vida chamado por Angular2 para indicar que Angular terminou de criar o componente. - não é exatamente isso. sinaliza que inicializou as ligações. O componente é criado anteriormente. Veja minha resposta
Max Koretskyi
22
Como em todas as "melhores práticas", acho que seria uma boa idéia também explicar por que você não deveria estar fazendo "trabalho" no construtor. Este artigo do líder da equipe Angular é denso, mas pode ajudar: misko.hevery.com/code-reviewers-guide/… Além disso, menos importância deve ser colocada nos encantamentos necessários para implementar o OnInit (isso é fácil de encontrar) e muito mais sobre o fato crítico de que as ligações de dados não estão disponíveis no construtor.
Reikim
2
Se o modo estrito for verdadeiro no tsconfig.jsonarquivo like "strict": true, você precisará inicializar os membros da classe no constructor, não no ngOnitlike FormGroup.
Rohit Sharma
174

O artigo A diferença essencial entre o Constructor e o ngOnInit no Angular explora a diferença de várias perspectivas. Esta resposta fornece a explicação da diferença mais importante relacionada ao processo de inicialização do componente, que também mostra a diferença de uso.

O processo de inicialização angular consiste nos dois estágios principais:

  • construção de árvore de componentes
  • executando a detecção de alterações

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

Quando Angular constrói uma árvore de componentes, o injetor do módulo raiz já está configurado para que você possa injetar quaisquer dependências globais. Além disso, quando Angular instancia uma classe 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 chamado no contexto do injetor; portanto, se você precisar de alguma dependência, esse é o único local para obtê-las.

Quando o Angular inicia a detecção de alterações, a árvore de componentes é construída e os construtores de todos os componentes da árvore foram chamados. Além disso, os nós de modelo de cada componente são adicionados ao DOM. O @Inputmecanismo de comunicação é 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 depois ngOnInit.

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

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

Portanto, o Angular inicia a inicialização do aplicativo. Como eu disse, primeiro cria classes para cada componente. Por isso, chama MyAppComponentconstrutor. Ele também cria um nó DOM, que é o elemento host do my-appcomponente. Em seguida, prossegue para a criação de um elemento host para o construtor child-compe chamado ChildComponent. Nesta fase, não está realmente preocupado com a iligação de entrada e quaisquer ganchos de ciclo de vida. Portanto, quando esse processo é concluído, o Angular termina com a seguinte árvore de visualizações de componentes:

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

Somente então executa a detecção de alterações e atualiza as ligações para as my-appchamadas e ngOnInitna classe MyAppComponent. Em seguida, prossegue para atualizar as ligações para as child-compchamadas e ngOnInitna classe ChildComponent.

Você pode executar sua lógica de inicialização no construtor ou ngOnInitdependendo do que você precisa disponível. Por exemplo, o artigo Aqui está como obter o ViewContainerRef antes que a consulta @ViewChild seja avaliada, mostra que tipo de lógica de inicialização pode ser necessária para ser executada no construtor.

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

Max Koretskyi
fonte
33
essa deve ser a resposta aceita. na verdade, explica o porquê, em vez de repetir mantras e afirmar the constructor should only be used to inject dependencies.
Stavm
1
@ yannick1976, obrigado! Confira os artigos referenciados
Max Koretskyi
@flobacca, você pode por favor refazer a pergunta, é difícil entender o que você está pedindo
Max Koretskyi
Por favor me corrija se eu estiver errado. Entendi que a árvore de componentes é construída primeiro e depois altera o processo de detecção. Você escreveu primeiro o construtor AppComponent é chamado (junto com as dependências resolvidas); depois, o construtor ChildComponent é chamado (junto com as dependências); depois, as ligações de entrada para AppComponent e OnInit são chamadas. Mas minha preocupação é que se eu adicionar ganchos de ciclo de vida a ambos os componentes, o fluxo será AppComponentConstructor - -> AppComponentOnInit - → ChildComponentConstructor - → ChildComponentOnInit Por que AppComponentOnInit está sendo chamado antes de ChildComponentConstructor
user2485435
1
@MaxKoretskyiakaWizard você estava certo. Cometi algum erro na configuração do meu aplicativo. está funcionando como descrito por você. angular-c7zjsx.stackblitz.io
user2485435
96

Eu acho que o melhor exemplo seria usar serviços. Digamos que eu queira pegar dados do meu servidor quando meu componente for 'Ativado'. Digamos que eu também queira fazer algumas coisas adicionais nos dados depois de obtê-los do servidor, talvez eu receba um erro e queira registrá-los de maneira diferente.

É realmente fácil com o ngOnInit em um construtor, 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<any>;

    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. Como garantir que tudo esteja em maiúsculas, não tenho muita certeza de como meus dados estão chegando.

Portanto, fica muito mais fácil usar o 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();
    };


}

Torna muito mais fácil a visualização e, portanto, apenas chamo minha função dentro do meu componente quando inicializo, em vez de ter que procurá-la em outro lugar. Realmente, é apenas mais uma ferramenta que você pode usar para facilitar a leitura e o uso no futuro. Também acho uma prática muito ruim colocar chamadas de função dentro de um construtor!

Morgan G
fonte
Seu exemplo pode ser simplificado se você apenas definir user_list como Observable. O Angular2 possui o canal assíncrono, para que não haja problemas.
DarkNeuron
@ Morgan, só para eu aprender uma coisa pequena aqui, por que você primeiro cria uma função getUserse depois a insere ngOnInit? Não é menos código simplesmente escrever no ngOnInit? Estou apenas me perguntando por que as pessoas fazem dessa maneira? É para que você possa reutilizar o código, se quiser? Obrigado.
Alfa Bravo
31
Como visto na resposta abaixo, isso não faz diferença se estiver no construtor. Esta não é uma resposta real para o objetivo.
Jimmy Kane
8
Não vejo como isso responde à pergunta. Por que você não pode simplesmente colocar o código no constructor?
CodyBugstein 26/10/2015
1
@Morgan porque você não pode apenas fazerconstructor(private _userService: UserService){ this.getUsers(); };
Ashley
82

OK, antes de tudo ngOnInitfaz parte do ciclo de vida do Angular , enquanto constructorfaz parte da classe JavaScript ES6 , então a principal diferença começa aqui! ...

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

ngOnInit vs construtor

No Angular2 +, costumamos constructorfazer isso DI(Dependency Injection)por nós, enquanto no Angular 1 isso acontecia chamando o método String e verificando qual dependência foi injetada.

Como você vê no diagrama acima, isso ngOnInitacontece depois que o construtor está pronto ngOnChnagese é acionado depois que o componente está pronto para nós. Toda inicialização pode acontecer neste estágio, uma amostra simples está injetando um serviço e o inicializa no init.

OK, também compartilho um código de exemplo para você ver, ver como usamos ngOnInite constructorno código abaixo:

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
fonte
1
Obrigado. essa deve ser a melhor resposta.
Don Dilanga 22/11/19
58

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

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

Citado no site oficial da angular:

  • ngOnChanges é chamado quando um valor de ligação de entrada ou saída é alterado
  • ngOnInit é chamado após o primeiro ngOnChanges

Portanto, você deve usar ngOnInitse o processamento de inicialização depende de ligações do componente (por exemplo, parâmetros de componente definidos com @Input), caso contrário, o construtor seria suficiente ...

Thierry Templier
fonte
49

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

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

No entanto, como ngOnInitacontece depois que o componente foi criado e os cheques ( ngOnChanges) foram chamados, você pode acessar o DOM neste momento.

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
fonte
3
Não. Em @ViewChildrenparticular, você precisa usar o ngAfterViewInitmétodo Veja aqui: stackoverflow.com/questions/46314734/…
AsGoodAsItGets
1
Obrigado, @AsGoodAsItGets por apontar isso. Eu já melhorou a resposta
Miroslav Jonas
38

Resposta curta e simples seria,

Constructor: constructoré uma default methodexecução ( por surdo ) quando o componente está sendo construído. Quando você cria an instanceuma classe, esse tempo também constructor(default method)é chamado. Portanto, 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 Angular2nele costumava-se injetar coisas como servicesquando um componente está sendo construído para uso posterior.

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

Portanto, seu construtor será chamado primeiro e o Oninit será chamado mais tarde, após o método do 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 do LifeCycle

Você pode verificar esta pequena demonstração que mostra a implementação de ambas as coisas.

micronyks
fonte
5
Eu acho que "construtor é algo que é executado ou chamado quando o componente é inicializado". é enganoso. O construtor é um recurso da classe e não do componente. Eu diria que a instância da classe só se torna um componente depois que o construtor foi chamado e Angular fez sua inicialização.
Günter Zöchbauer 03/03
Sim alterou a declaração que você pode verificar agora.
micronyks
1
Hmm, IMHO ainda é o mesmo "construtor (método padrão) é algo que é executado ou chamado quando o componente é construído.". Não é chamado apenas quando um componente é construído, mas também para serviços ou quando código new MyClass()é executado. Eu acho que é enganoso dizer que construtores são sobre componentes, eles são sobre classes e instâncias de inicialização dessas classes. Por acaso, um componente é uma classe dessas. Caso contrário, acho que é uma boa resposta.
Günter Zöchbauer 03/03
2
Sim absolutamente. Esqueci de mencionar que, quando você cria um objeto de uma classe, esse tempo constructortambém é chamado. Mas essa resposta foi escrita no contexto angular2. Para saber a melhor resposta, você deve conhecer o básico sobre OOPs. Ainda vou atualizar a resposta.
micronyks
@ GünterZöchbauer, não acho que seja uma afirmação correta que seja um recurso da classe e não do componente . Da perspectiva da linguagem de programação, sim, isso está correto. Mas posso trabalhar com componentes sem nenhum gancho de ciclo de vida. Mas não posso trabalhar com um componente sem um construtor se precisar de DI porque esse é o único local injetável. Veja minha resposta
Max Koretskyi
20

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

Variáveis ​​de nível de classe

Normalmente, você declarará aqui todas as suas variáveis ​​que serão usadas no restante do 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 mudarem.

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

Construtor

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

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

isso criará automaticamente as variáveis ​​no nível da classe, para que você tenha acesso customService.myMethod()sem precisar fazer isso manualmente.

NgOnInit

NgOnit é um gancho de ciclo de vida fornecido pela estrutura Angular 2. Seu componente deve ser implementado OnInitpara usá-lo. Esse gancho do ciclo de vida é chamado depois que o construtor é chamado e todas as variáveis ​​são inicializadas. A maior parte da sua inicialização deve estar aqui. Você terá a certeza de que o Angular inicializou seu componente corretamente e pode começar a fazer qualquer lógica necessária em OnInitvez de fazer as coisas quando o componente não terminar 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 a estrutura Angular 2 e precisar interagir com determinados eventos do ciclo de vida, use os métodos fornecidos pela estrutura para evitar problemas.

Eduardo Dennis
fonte
19

Para testar isso, escrevi esse código, emprestando do 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;
  }

}

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 ***  
abbaf33f
fonte
18

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

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

Antipadrão do construtor

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

Uma receita usual para separar a lógica de inicialização do construtor de classe é movê-la para outro método como init:

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

  init() {...}
}

ngOnInit pode servir a esse propósito em componentes e diretrizes:

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

ngOnInit() {
  // rest of initialization code
}

Injeção de dependência

O papel principal dos construtores de classe no Angular é a injeção de dependência. Os construtores também são usados ​​para anotação DI no TypeScript. Quase todas as dependências são atribuídas como propriedades à instância da classe.

O construtor médio de componente / diretiva já é grande o suficiente porque pode ter assinatura de várias linhas devido a dependências, colocando uma lógica de inicialização desnecessária no corpo do construtor contribui para o antipadrão.

Inicialização assíncrona

O construtor de inicialização assíncrona geralmente pode ser considerado antipadrão e tem cheiro, porque a instanciação de classe termina antes da rotina assíncrona, e isso pode criar condições de corrida. Se não for esse o caso, ngOnInite outros ganchos do ciclo de vida são melhores para isso, principalmente porque eles podem se beneficiar da asyncsintaxe:

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 a que um componente não deve aparecer no erro de inicialização), a rotina de inicialização assíncrona deve ocorrer antes da instanciação do componente e ser movida para o componente pai, a proteção do roteador etc.

Teste de unidade

ngOnInité mais flexível que um construtor e fornece alguns benefícios para os testes de unidade, explicados em detalhes nesta resposta .

Considerando que ngOnInitnão é chamado automaticamente na compilação de componentes em testes de unidade, os métodos chamados ngOnInitpodem ser espionados ou zombados após a instanciação do componente.

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

Herança

As classes filho podem apenas aumentar os construtores, não substituí-los.

Como thisnão pode ser referido anteriormente super(), isso coloca restrições na precedência de inicialização.

Considerando que o componente Angular ou a diretiva usa ngOnInitpara lógica de inicialização sem distinção de tempo, as classes filho podem escolher se super.ngOnInit()é chamado e quando:

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

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

Estus Flask
fonte
12

As respostas acima não respondem realmente a esse aspecto da pergunta original: O que é um gancho de ciclo de vida? Demorei um pouco para entender o que isso significa até eu pensar 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 script de ciclo de vida: Nascido, Bebê, Escola primária, Adulto jovem, Adulto de meia idade, Adulto sênior, Morto, Descartado.

3) Digamos que você queira ter uma função para criar filhos. Para evitar que isso se torne complicado e bem-humorado, você deseja que sua função seja chamada apenas durante o estágio do Jovem Adulto da vida do componente humano. Portanto, você desenvolve um componente que só é ativo quando o componente pai está no estágio Jovem Adulto. Os ganchos ajudam você a fazer isso sinalizando esse estágio da vida e deixando seu componente agir sobre ele.

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

Preston
fonte
7

O construtor é um método em JavaScript e é considerado um recurso da classe em es6. Quando a classe é instanciada, ele executa imediatamente o construtor, seja ele usado na estrutura Angular ou não. 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 classe "ConstructorTest" é instanciada abaixo; portanto, chama internamente o construtor (Tudo isso acontece por JavaScript (es6) no Angular).

new CONSTRUCTORTEST();

É por isso que há ngOnInit gancho de ciclo de vida em Angular.ngOnInit torna quando Angular terminar de iniciar 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 classe como abaixo, que acontece com execuções imediatas do método construtor.

let instance = new NGONINITTEST();

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

instance.ngOnInit();

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

A resposta é injeções de dependências . Como mencionado anteriormente, o construtor chama pelo mecanismo JavaScript imediatamente quando a classe é instanciada (antes de chamar ngOnInit por Angular), de modo que o texto datilografado nos ajuda a obter o tipo de dependência definido no construtor e finalmente informa Angular que tipo de dependências queremos usar nesse componente específico.

Negin
fonte
7

Duas coisas a serem observadas aqui:

  1. O construtor é chamado sempre que um objeto é criado para essa classe.
  2. ngOnInit chamado depois que o componente é criado.

Ambos têm usabilidade diferente.

UniCoder
fonte
5

construtor() é o método padrão no ciclo de vida do componente e é usado para injeção de dependência. O construtor é um recurso de texto datilografado.

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

ou seja:

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

como mencionado acima ngOnChanges()é chamado quando um valor de ligação de entrada ou saída é alterado.

Shajin Chandran
fonte
4

Ambos os métodos têm objetivos / responsabilidades diferentes. A tarefa do construtor (que é um recurso suportado por idioma) é garantir que a representação invariável seja mantida. Caso contrário, é indicado para garantir que a instância seja válida, fornecendo valores corretos aos membros. Cabe ao desenvolvedor decidir o que 'correto' significa.

A tarefa do método onInit () (que é um conceito angular) é permitir invocações de método em um objeto correto (representação invariável). Cada método, por sua vez, deve garantir que a representação invariável seja mantida quando o método terminar.

O construtor deve ser usado para criar objetos 'corretos', o método onInit oferece a oportunidade de chamar chamadas de método em uma instância bem definida.

Bruno Ranschaert
fonte
4

Construtor: o método construtor em uma classe ES6 (ou TypeScript neste caso) é um recurso da própria classe, e não um recurso Angular. Está fora de controle da Angular quando o construtor é chamado, 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 Angular diretamente. É por isso que o gancho do ciclo de vida ngOnInit (e $ onInit no AngularJS) foi criado. Tendo isso em mente, existe um cenário adequado para o uso do construtor. É quando queremos utilizar a injeção de dependência - essencialmente para "ligar" as dependências ao componente.

Como o construtor é inicializado pelo mecanismo JavaScript, o TypeScript nos permite dizer ao Angular quais dependências precisamos mapear em uma propriedade específica.

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

Essa fase inclui a primeira passagem na 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 isso, as propriedades @Input () estão disponíveis dentro do ngOnInit, mas são indefinidas dentro do construtor, por design

Vishal Gulati
fonte
2

O construtor é o primeiro e acontece algumas vezes quando os dados @input são nulos! então usamos o Constructor para declarar serviços e o ngOnInit acontece depois. Exemplo para o contrutor:

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

Exemplo para onInit:

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

Eu acho que onInit é como InitialComponents () no winForm.

user1012506
fonte
1

Nos ciclos de vida angulares

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

2) Próximo ciclo de vida da chamada angular

Ganchos angulares do ciclo de vida

ngOnChanges -> Chamada na ligação de parâmetros de diretiva.

ngOnInit -> Iniciar renderização angular ...

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

Shahsavan muçulmano
fonte
1

O constructoré chamado quando "instanciates / construções" angular do componente. O ngOnInitmétodo é um gancho que representa a parte de inicialização do ciclo de vida do componente. Uma boa prática é usá-lo apenas para injeção de serviço :

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

Mesmo que seja possível, você não deve fazer algum "trabalho" por dentro. Se você deseja iniciar alguma ação que deve ocorrer na "inicialização" do componente, use ngOnInit:

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

Além disso, ações que envolvem propriedades de entrada , provenientes de um componente pai, não podem ser executadas no contratante. Eles devem ser colocados no ngOnInitmétodo ou em outro gancho. É o mesmo para o elemento relacionado à visualização (o DOM), por exemplo, 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
fonte
0

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

ngOnInit(), ngOnChanges()E ngOnDestroy()etc, são métodos de ciclo de vida. ngOnChanges()será o primeiro a ser chamado, antes ngOnInit(), quando o valor de uma propriedade vinculada for alterado, NÃO será chamado se não houver alteração. ngOnDestroy()é chamado quando o componente é removido. Para usá-lo, OnDestroyprecisa ser implementeditado pela classe.

xameeramir
fonte
1
Concordo, isso é breve e claro. Por exemplo, constructor () é para adicionar objetos de serviço, ngOnInit () é para manipular componentes com as chamadas de função de serviço necessárias.
Steve
0

Encontrei a resposta e tentei traduzi-la para o inglês: essa pergunta ainda surgiu, mesmo em entrevistas técnicas. De fato, há uma grande semelhança entre os dois, mas também existem algumas diferenças.

  • O construtor faz parte do ECMAScript. Por outro lado, ngOnInit () é uma noção de angular.

  • Podemos chamar os construtores em todas as classes, mesmo se não usarmos Angular

  • Ciclo de vida: O construtor é chamado antes de ngOnInt ()

  • No construtor, não podemos chamar elementos HTML. No entanto, em ngOnInit () nós podemos.

  • Geralmente, chamadas de serviços no ngOnInit () e não no construtor

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

doudou
fonte
0

Construtor

A função construtor vem com todas as classes, construtores não são específicos para Angular, mas são conceitos derivados de projetos orientados a objetos. O construtor cria uma instância da classe de componente.

OnInit

A ngOnInitfunção é um dos métodos de ciclo de vida de um componente Angular. Os métodos do ciclo de vida (ou ganchos) nos componentes Angular permitem executar um pedaço de código em diferentes estágios da vida útil de um componente. Diferente do método construtor, o ngOnInitmétodo vem de uma interface Angular ( OnInit) que o componente precisa implementar para usar esse método. O ngOnInitmétodo é chamado logo após a criação do componente.

DeC
fonte
0

O Construtor é executado quando a classe é instanciada. Não tem nada a ver com o angular. É o recurso do Javascript e o Angular não tem controle sobre ele

O ngOnInit é específico do Angular e é chamado quando o Angular inicializa o componente com todas as suas propriedades de entrada.

As propriedades @Input estão disponíveis no gancho do ciclo de vida do ngOnInit. Isso ajudará você a fazer algumas coisas de inicialização, como obter dados do servidor back-end, etc., para exibir na exibição

As propriedades @Input são mostradas como indefinidas dentro do construtor

dasunse
fonte
-1

Construtor é uma função executada quando o componente (ou outra classe) é construído.

O ngOnInit é uma função pertencente a um grupo de métodos do ciclo de vida do componente e eles são executados em um momento diferente do nosso componente (é por isso que o nome ciclo de vida). Aqui está uma lista de todos eles:

insira a descrição da imagem aqui O construtor será executado antes de qualquer função do ciclo de vida.

Przemek Struciński
fonte