Подтвердить что ты не робот

Почему ngOnInit вызывается дважды?

Я пытаюсь создать новый компонент, ResultComponent, но его метод ngOnInit() вызывается дважды, и я не знаю, почему это происходит. В коде ResultComponent наследует @Input от родительского компонента mcq-component.

Вот код:

Родительский компонент (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){}
    ....
}

Дочерний компонент (result-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);
    }
}

При запуске console.log появляется два раза, первый раз показывает правильный массив, но второй раз выдает undefined. Я не смог понять это: почему ngOnInit в ResultComponent вызывается дважды?

4b9b3361

Ответ 1

Почему он вызывается дважды

Прямо сейчас, если при обнаружении изменений содержимого/просмотра дочерних элементов компонента происходит ошибка, ngOnInit будет вызываться дважды (см. в DynamicChangeDetector). Это может привести к последующим ошибкам, которые скрывают исходную ошибку.

Эта информация исходит из проблема github


Итак, кажется, что ваша ошибка может возникнуть в другом месте вашего кода, связанного с этим компонентом.

Ответ 2

Это происходило со мной из-за неисправного компонента html. Я забыл закрыть тег селектора в компоненте хоста. Таким образом, у меня был этот <search><search>, а не <search></search> - обратите внимание на синтаксическую ошибку.

Поэтому, связанный с ответом @dylan, проверьте структуру компонента html и структуру его родителя.

Ответ 3

Ну, проблема в моем случае была в том, как я загружал дочерние компоненты. В моем объекте метаданных @NgModule, я передавал дочерний компонент в bootstap, а также родительский компонент . > . Передача дочерних компонентов в свойстве bootstap была сброса моих дочерних компонентов свойств и создания OnInit() дважды.

@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
})

Ответ 4

Если вы использовали platformBrowserDynamic().bootstrapModule(AppModule); в app.module.ts, прокомментируйте это и попробуйте. У меня такая же проблема. Я думаю, что это помогает

Ответ 5

Поместите это здесь, в случае, если кто-то окажется здесь. NgOnInit также можно вызывать дважды, если тип кнопки браузера по умолчанию "отправить", скажем, если у вас есть ниже, NgOnInit из NextComponent будет вызываться дважды в Chrome:

<button class="btn btn-primary" (click)="navigateToNextComponent()">

Чтобы исправить это, установите тип:

<button class="btn btn-primary" type="button" (click)="navigateToNextComponent()">

Ответ 6

Это может произойти, потому что вы установили AppComponent качестве маршрута по умолчанию

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

Примечание: AppComponent вызывается по умолчанию в angular поэтому не нужно вызывать его

Ответ 7

Это происходит всякий раз, когда возникают ошибки шаблона.

В моем случае я использовал неправильную ссылку на шаблон и исправил исправление моей проблемы.

Ответ 8

ngOnInit() перехватывает только один раз после создания всех директив. Если у вас есть подписка внутри ngOnInit() и она не отписана, то она будет запущена снова, если данные подписки изменятся.

В следующем примере Stackblitz у меня есть подписка внутри ngOnInit() и утешает результат. Он утешается дважды, потому что загружается один раз, а данные изменяются и загружаются снова.

Stackblitz

Ответ 9

В моем случае это происходит, когда Component реализует и OnChanges, и OnInit. Попробуйте удалить один из этих классов. Вы также можете использовать метод ngAfterViewInit, он запускается после инициализации представления, так что он гарантированно вызывается один раз.

Ответ 10

Это случилось со мной, потому что у меня был неназванный <router-outlet> внутри *ngFor. Он загружается для каждой итерации в цикле.

В этом случае решением будет иметь уникальное имя для каждой торговой точки или убедиться, что в DOM одновременно присутствует только одно (возможно, w/an *ngIf).

Ответ 11

У меня была похожая проблема, я вызывал компонент, а затем ссылался на тот же компонент через роутер-розетку.

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

И маршрут выхода также указывал на макет.

Ответ 12

Для меня это произошло потому, что я дважды зарегистрировал один и тот же компонент в Route:

{
        path: 'meal-services',
        children: [
          {
            path: '',
            component: InitTwiceComponent,
            canActivate: [AppVendorOpsGuard],
            data: { roleWhitelist: [UserRoles.Manage] }
          },
          {
            path: ':itemID',
            component: InitTwiceComponent,
            canActivate: [AppVendorOpsGuard],
            data: { roleWhitelist: [UserRoles.Manage] }
          }]
      },
}

Ответ 13

В моем случае я не отписался от всех подписок, которые были у меня внутри ngOnInit. Я просто отписался от всех подписок в ngOnDestroy, и это решило мою проблему.

Ответ 14

У меня похожая проблема, я уже проверил плохо закрывающие теги, я объявляю свой компонент в SharedModule и экспортирую его туда, я пытался удалить platformBrowserDynamic().bootstrapModule(AppModule);, но затем приложение не компилируется... может кто-нибудь мне помочь? Angular 5 ngOnInit вызывается более одного раза