왜 ngOnInit가 두 번 호출됩니까?
새로운성구요만소합니다고들려를▁new,▁component▁create다합▁to▁i니를 만들려고 합니다.ResultComponent
그러나 그것은ngOnInit()
메소드가 두 번 호출되고 있는데 왜 이런 일이 일어나는지 모르겠어요. 에서코드,ResultComponent
@Input
구성 요소에서mcq-component
.
코드는 다음과 같습니다.
상위 구성요소(MCQ 구성요소)
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
는 두, 첫 배열을 두 는 는 두 번 표 됩 니 시 다 첫 른 지 만 하 을 표 니 다 합 제 번 는 공 째 두 시 배 열 올 는 바 째 번 니 ▁is 다 ▁showing 합 ▁up ▁two는 ▁but , 제공는째번▁times▁the첫▁the두▁gives▁the두다니▁array▁correct번▁it지째됩만undefined
요: 왜 그알아수낼없을다니었: 왜가는나습것.ngOnInit
ResultComponent
두 번이나 전화를 받았습니까?
두 번 호출되는 이유
현재 구성 요소의 콘텐츠/뷰 자식 변경을 감지하는 동안 오류가 발생하면 ngOnInit가 두 번 호출됩니다(DynamicChangeDetector 참조).이로 인해 원래 오류를 숨기는 확인할 메일 오류가 발생할 수 있습니다.
이 정보는 이 Github 문제에서 가져옵니다.
따라서 당신의 실수는 이 구성 요소와 관련된 코드의 다른 부분에서 발생한 것으로 보입니다.
이것은 HTML 구성 요소의 결함 때문에 저에게 일어난 일입니다.호스트 구성 요소에서 선택 도구 태그를 닫는 것을 잊었습니다.그래서 저는 이것을 가지고 있었습니다.<search><search>
에 <search></search>
구문 오류를 기록합니다.
따라서 @dylan 답변과 관련하여 구성 요소 html 구조와 상위 구조를 확인하십시오.
제 경우 문제는 하위 구성요소를 부트스트랩하는 방식이었습니다.@NgModule decorator의 메타데이터 개체에서 bootstap 속성의 'child component'와 함께 'parent component'를 전달하고 있었습니다.부트스탭 속성에서 자식 구성 요소를 전달하는 것은 자식 구성 요소 속성을 재설정하고 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
})
을 사용한 platformBrowserDynamic().bootstrapModule(AppModule);
app.try.app.app.ts.ts에서 댓글을 달 수 있습니다.저도 같은 문제가 있었습니다.이게 도움이 될 것 같습니다.
는 설하기때이발수있생습다니할문가제문을 할 수 .AppComponent
로서.
RouterModule.forRoot([
{ path: '', component: AppComponent } // remove it
])
참조: AppComponent
으로 에서기호다니출에서 됩니다.angular
따라서 아래와 같이 다시 호출할 필요가 없습니다.
@NgModule({
declarations: [
AppComponent,
],
bootstrap: [AppComponent] // bootstraping here by default
})
export class AppModule { }
누군가 여기로 올 경우를 대비해서 이걸 여기에 두는 것.브라우저의 기본 버튼 유형이 "제출"인 경우 NgOnInit를 두 번 호출할 수도 있습니다. 예를 들어, 아래와 같은 것이 있으면 크롬에서 NgOnInit가 두 번 호출됩니다.
<button class="btn btn-primary" (click)="navigateToNextComponent()">
수정하려면 유형을 설정합니다.
<button class="btn btn-primary" type="button" (click)="navigateToNextComponent()">
그ngOnInit()
모든 디렉티브가 인스턴스화된 후 한 번만 후크가 실행됩니다.▁inside▁you▁ngOnInit()
구독을 취소하지 않고 구독한 데이터가 변경되면 다시 실행됩니다.
다음 Stackblitz 예제에서는 내부에 구독이 있습니다.ngOnInit()
그리고 결과를 위로합니다.한 번 로드하면 데이터가 변경되고 다시 로드되기 때문에 콘솔이 두 번 작동합니다.
이 문제는 템플릿 오류가 있을 때마다 발생합니다.
저의 경우 잘못된 템플릿 참조를 사용하여 문제를 해결했습니다.
제 경우, 빌드에서 각 파일 main-es5.js 및 main-es2015.js의 복제를 생성하여 *-es5.js의 복제를 모두 삭제하고 작동했습니다.
그것도 당신의 경우라면, 중복을 삭제하지 말고 그 속성을 추가하세요.
<script src="elements-es5.js" nomodule defer>
<script src="elements-es2015.js" type="module">
제가 이름을 밝히지 않은 상태에서 이런 일이 벌어졌습니다.<router-outlet>
의 *ngFor
루프의 각 반복에 대해 로드되었습니다.
은 각 한 이름을 와 an an an an an an an an an an an an an an an an an an an an an an an an an an an an an DOM an an an an an an an an an an an an an an an an an an an an an an an an an an an *ngIf
).
Route:에서 동일한 구성 요소를 두 번 등록했기 때문에 이 문제가 발생했습니다.
{
path: 'meal-services',
children: [
{
path: '',
component: InitTwiceComponent,
canActivate: [AppVendorOpsGuard],
data: { roleWhitelist: [UserRoles.Manage] }
},
{
path: ':itemID',
component: InitTwiceComponent,
canActivate: [AppVendorOpsGuard],
data: { roleWhitelist: [UserRoles.Manage] }
}]
},
}
이 문제는 다음과 같은 라우터 출구가 여러 개 있는 경우에 발생할 수 있습니다.
<ng-container *ngIf="condition">
<div class="something">
<router-outlet></router-outlet>
</div>
</ng-container>
<ng-container *ngIf="!condition">
<div class="something-else">
<router-outlet></router-outlet>
</div>
</ng-container>
이렇게 하면 생성자를 두 번 호출할 수도 있습니다.가 두 번가 두 번 인데, 이는 가 자가두두번사구증생며요, 구내발다니합생있정때 안에 때 정확히 입니다.*ngIf
로 전환됩니다.
이를 디버깅하는 유용한 방법은 다음과 같이 rnd라는 클래스 변수를 만드는 것입니다.
rnd = Math.random()
console.log를 생성자 및 ngOnInit 내부에 저장합니다.값이 변경되면 두 번째 호출 시 구성 요소의 새 인스턴스가 있고 동일한 인스턴스가 두 번 호출되지 않음을 알 수 있습니다.이렇게 해도 문제가 해결되지는 않지만 문제를 나타낼 수 있습니다.
이 경우 Component가 OnChanges와 OnInit를 모두 구현할 때 발생합니다.이 클래스 중 하나를 제거합니다.또한 ngAfterView를 사용할 수 있습니다.init 메서드는 뷰가 초기화된 후 트리거되므로 한 번 호출됩니다.
저도 비슷한 문제가 있었습니다. 구성 요소를 요청한 다음 라우터 콘센트를 통해 동일한 구성 요소를 참조하고 있었습니다.
<layout>
<router-outlet></router-outlet>
</layout>
그리고 출구 경로도 레이아웃을 가리키고 있었습니다.
이것은 저에게 어린이 구성요소에서 일어난 일입니다.하위 구성 요소는 *ngIf를 사용하여 특정 조건이 충족될 때 표시합니다.나의 해결책은 ngIf를 ngClass로 대체하는 것입니다.
HTML에서:
<component [ngClass]="isLoading?'hide':'show'>"
CSS:
.show{ display: block; }
.hide{ display: none; }
제가 2021년에 이 문제를 우연히 발견했을 때, 저는 최근에 오래된 ng4에서 더 최근의 ng10으로 이주했습니다.그러나 앱이 index.jsp를 통해 모노리식 Java 백엔드에 통합되어 있어 제대로 마이그레이션하지 않았습니다.
유사한 위치에 있는 경우 다음을 확인합니다.<script>
는 "". *-es2015.js 파일이어야 .type="module"
에는 *-es5.js에는 *-es5.js라는 이름이 있어야 .nomodule defer
집합, 즉:
<script src=".../main-es5.js" nomodule defer></script>
<script src=".../main-es2015.js" type="module"></script>
저의 경우 ngOnInit 내에 있는 모든 구독을 취소하지 않았습니다.방금 ngOnDestroy의 모든 구독에서 구독을 취소하여 문제가 해결되었습니다.
나의 경우 app.component.html에서 이것을 일으킨 것은 html 오류였습니다.
<icpm-la-test><icpm-la-test>
대신에
<icpm-la-test></icpm-la-test>
닫는 태그 대신 여는 태그가 두 개 있었고, 콘솔에 오류가 없었고 ngOnInit가 두 번 호출되어 구독과 관련하여 여러 API 호출이 발생한 것을 제외하고는 기능이 잘 작동했습니다.
실수로 구성 요소를 두 번 시작한 것일 수 있습니다.이는 몇 가지 이유 때문일 수 있습니다.
을 가져왔습니다.
AppRoutingModule
둘 이상의 모듈로.앱 전체에서 검색하고 해당 앱에만 포함되도록 합니다.AppModule
.을 가져왔습니다.
AppModule
다른 모듈로 이동합니다. 당신의 을 할 수 .AppRoutingModule
제1항에 따라개 의 두개이있다니가 있습니다.
<router-outlet>
당신의 마크업에서. 개의 경로가 둘 가 필요하기 스러울 수 .<router-outlet>
각해야 합니다.<router-outlet>
때때로 실제 출력이 무엇인지 확인하기 위해 부모 내부에 중첩된 각 구성 요소를 복사하는 것이 더 쉽습니다.그러면 당신은 당신이 여분을 갖게 되었는지 볼 수 있습니다.<router-outlet>
래퍼 구성 요소는 AppRoutingModule과 하위 구성 요소 내부에 지정되어 있습니다.종종 머리글, 바닥글, 메뉴 등과 같은 표준 레이아웃을 처리하는 래퍼 구성요소가 있습니다.그러면 내 아이의 모든 경로가 내 안에 설정될 때 이 안에 있을 것입니다.
AppRoutingModule
이 요소를 다른 요소 할 수 이미 할 수 있습니다.AppRoutingModule
이것은 추가로 이어질 것입니다.<router-outlet>
.
XComponent를 배치했습니다.
부트스트랩: [AppComponent, XComponent]
app.s.ts.에
XComponent ngOnInit를 제거한 후 한 번만 트리거되었습니다.
앵커 태그에 href="#" 속성이 있어서 이런 일이 발생했습니다. 앵커 태그에 사용하지 마십시오.아래와 같은 각도 코드에 따라 routerLink를 사용하고 appComponent.ts에 ngInit(0 메소드)가 있는 것을 피하려고 하면 이 문제가 해결됩니다.
<a class="nav-link" [routerLink]="['/login']"> Sign In. </a>
은 해책다같습다니음과제은을 사용하는 것이었습니다.ngIf
정의되지 않은 입력을 방지하기 위한 구성 요소의 경우 다음과 같습니다.
<result-comp *ngIf="answers" [answers]="answers"></result-comp>
저의 경우, Login 페이지가 Sign Out 버튼을 누른 후 두 번 호출되는 것이 문제였습니다.사인 아웃 버튼의 구문이 잘못되었습니다.문제를 일으키는 코드는 다음과 같습니다.
<a routerLink="/login">
<i class="fa fa-sign-out" (click)="logout()"></i>
</a>
아이콘 태그에서 클릭 이벤트를 제거하고 링크 태그에 넣음으로써 문제가 해결되었습니다.
<a routerLink="/login" (click)="logout()">
<i class="fa fa-sign-out"></i>
</a>
main.ts 파일을 확인합니다.기본적으로 Angular 앱에는 플랫폼 BrowserDynamic()에 대한 이 두 개의 별도 참조가 있다고 생각합니다.저는 두 번째 것에 대해 의견을 제시했고 효과가 있었습니다.
const platform = platformBrowserDynamic(); 플랫폼.부트스트랩 모듈(앱 모듈);
//platformBrowserDynamic().bootstrapModule(AppModule) // .module(err = > console.error(err));
언급URL : https://stackoverflow.com/questions/38787795/why-is-ngoninit-called-twice
'bestsource' 카테고리의 다른 글
php SimpleXML 하위 항목이 존재하는지 확인 (0) | 2023.08.07 |
---|---|
ConnectionString 속성이 초기화되지 않았습니다."를 수정하는 방법 (0) | 2023.08.07 |
조건부 UPDATE MariaDB(MySQL) (0) | 2023.08.07 |
선택한 워크시트를 excel 파일에서 pdf로 파이썬으로 인쇄 (0) | 2023.08.07 |
npm WARN에서 더 이상 사용되지 않는 core-js@2.6.11: core-js@<3은 더 이상 유지 관리되지 않으며 문제의 수 때문에 사용하지 않는 것이 좋습니다. (0) | 2023.08.07 |