vida - onload angular 6




Por que ngOnInit é chamado duas vezes? (9)

Eu estou tentando criar novo componente, ResultComponent , mas seu método ngOnInit() está sendo chamado duas vezes e eu não sei porque isso está acontecendo. No código, ResultComponent herda @Input do componente pai mcq-component .

Aqui está o código:

Componente pai (MCQComponent)

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

@Component({
    selector: 'mcq-component',
    template: `
        <div *ngIf = 'isQuestionView'>
            .....
        </div>
        <result-comp *ngIf = '!isQuestionView' [answers] = 'ansArray'><result-comp>
    `,
    styles: [
        `
            ....
        `
    ],
    providers: [AppService],
    directives: [SelectableDirective, ResultComponent]
})
export class MCQComponent implements OnInit{
      private ansArray:Array<any> = [];
    ....
    constructor(private appService: AppService){}
    ....
}

Componente filho (resultado-comp)

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

@Component({
    selector:'result-comp',
    template: `
        <h2>Result page:</h2>

    `
})
export class ResultComponent implements OnInit{
    @Input('answers') ans:Array<any>;

    ngOnInit(){
        console.log('Ans array: '+this.ans);
    }
}

Quando executado, console.log está aparecendo duas vezes, a primeira vez que mostra a matriz correta, mas a segunda vez dá undefined . Eu não consegui descobrir: por que ngOnInit no ResultComponent chamado duas vezes?


Por que é chamado duas vezes

No momento, se ocorrer um erro durante a detecção de alterações de conteúdo / visualização de um componente, ngOnInit será chamado duas vezes (visto em DynamicChangeDetector). Isso pode levar a erros de acompanhamento que ocultam o erro original.

Esta informação vem desta questão do github

Assim, parece que seu erro pode ter origem em outro lugar no código, relacionado a esse componente.


Bem, o problema no meu caso foi a maneira que eu estava inicializando os componentes filho. No objeto de metadados do meu @NgModule decorator, eu estava passando o ' componente filho ' na propriedade bootstap junto com ' parent component '. Passar os componentes filhos na propriedade bootstap estava redefinindo as propriedades dos componentes filhos e fazendo com que OnInit () disparasse duas vezes.

@NgModule({
imports: [ BrowserModule,FormsModule ], // to use two-way data binding ‘FormsModule’
declarations: [ parentComponent,Child1,Child2], //all components
//bootstrap: [parentComponent,Child1,Child2] // will lead to errors in binding Inputs in Child components
bootstrap: [parentComponent] //use parent components only
})


Eu tive um problema semelhante, eu estava ligando para um componente e, em seguida, fazendo referência ao mesmo componente através da saída do roteador.

<layout>
  <router-outlet></router-outlet>
</layout>

E a rota de saída também apontava para Layout.


Isso acontece sempre que houver algum erro de modelo.

No meu caso, eu estava usando uma referência de modelo errada e corrigindo isso corrigiu meu problema.


Isso estava acontecendo comigo por causa de um componente defeituoso html. Eu tinha esquecido de fechar a tag do seletor no componente host. Então eu tive este <search><search> , em vez de <search></search> - tome nota do erro de sintaxe.

Então, relacionado à resposta @dylan, verifique sua estrutura html de componente e a de seu pai.


Isso pode acontecer porque você definiu o AppComponent como sua rota padrão

RouterModule.forRoot([
    { path: '', component: AppComponent }  // remove it
])

Nota: AppComponent é chamado por padrão em angular então não precisa chamá-lo


No meu caso, isso acontece quando o Component implementa OnChanges e OnInit . Tente remover uma dessas classes. Você também pode usar o método ngAfterViewInit , ele é acionado após a visualização inicializada, para que seja garantido que seja chamado uma vez.


O ngOnInit() conecta apenas uma vez depois que todas as diretivas são instanciadas. Se você tem uma assinatura dentro de ngOnInit() e não está cancelada, ela será executada novamente se os dados assinados forem alterados.

No seguinte exemplo do Stackblitz, tenho uma assinatura dentro de ngOnInit() e console o resultado. Ele consola duas vezes porque carrega uma vez e as alterações de dados e carrega novamente.

Stackblitz


se você usou platformBrowserDynamic().bootstrapModule(AppModule); em app.module.ts comentá-lo e tente. Eu tive o mesmo problema. Acho que isso ajuda







ngoninit