with - what is oninit angular




Diferença entre o Construtor e o ngOnInit (16)

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

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


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


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

A diferença prática é como o ngOnInit afeta a estrutura do código. 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 comum para separar a lógica de inicialização do construtor de classe é movê-la para outro método como o init :

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

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

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

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

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 o caso, o ngOnInit e outros ganchos do ciclo de vida são melhores para isso, principalmente porque eles podem se beneficiar da sintaxe async :

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

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 o teste de unidade, que são explicados em detalhes nesta resposta .

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

Em casos excepcionais, o ngOnInit pode 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 this não pode ser referido antes de super() , isso coloca restrições na precedência de inicialização.

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

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

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


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.


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.

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

  init() {...}
}

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(
  public foo: Foo,
  /* verbose list of dependencies */
) {
  // time-sensitive initialization code
  this.bar = foo.getBar();
}

ngOnInit() {
  // rest of initialization code
}

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

NgOnInit

NgOnit é um gancho de ciclo de vida fornecido pela estrutura Angular 2. Seu componente deve implementar o OnInit para 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 no OnInit em vez de fazer coisas quando o componente não terminar de carregar corretamente.

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

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.


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 forma 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 certeza de como meus dados estão chegando.

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


}

Isso 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 procurar 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 em um construtor!


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.


O constructor é chamado quando o Angular "instancia / constrói" o componente. O método ngOnInit é 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 método ngOnInit ou 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
};

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. Portanto, é 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 classe "ConstructorTest" é instanciada abaixo; portanto, chama internamente o construtor (Tudo isso acontece por JavaScript (es6) no Angular).

new CONSTRUCTORTEST();

É por isso que existe o gancho do 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 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ências definidas no construtor e finalmente informa Angular que tipo de dependências queremos usar nesse componente específico.


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.


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 incluir 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 o ngOnInit se o processamento de inicialização depender de ligações do componente (por exemplo, parâmetros do componente definidos com @Input ), caso contrário, o construtor seria suficiente ...


Vou apenas adicionar uma coisa importante que foi ignorada nas explicações acima e explica quando você DEVE usar o 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 ngOnInit acontece depois que o componente foi criado e as verificações ( ngOnChanges ) são chamadas, 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
  }
}

o

 @Input 

O mecanismo de comunicação é processado como parte da fase de detecção de alterações a seguir, para que as ligações de entrada não estejam disponíveis no construtor.


Resposta curta e simples seria,

Constructor : o constructor é um default method executado ( por surdo ) quando o componente está sendo construído. Quando você cria an instance de uma classe, esse tempo também é chamado de constructor(default method) . Portanto, em outras palavras, quando um 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 no Angular2 ele injeta coisas como services quando o componente está sendo construído para uso posterior.

OnInit : ngOnInit é o gancho do ciclo de vida do componente que é executado primeiro após o constructor(default method) quando 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.


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:

O construtor será executado antes de qualquer função do ciclo de vida.


OK, primeiro o ngOnInit faz parte do ciclo de vida do Angular , enquanto o constructor faz 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.

No Angular2 +, usamos o constructor para fazer o DI(Dependency Injection) para 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, o ngOnInit está acontecendo depois que o construtor está pronto e o ngOnChnages e é acionado após o componente estar 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, veja como usamos o ngOnInit e o constructor no 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!');
  }
}

constructor () é 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.

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

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





ngoninit