Angular 17.3中NgOnInit重复执行致调用栈错误(含Signal)
Angular 17.3中NgOnInit无限循环及组件重复加载问题(已修复)
问题现象
在Angular 17.3版本中出现异常行为:
ngOnInit钩子会先执行if分支(调用getProject接口更新信号),随后执行else分支,之后重复执行else分支超过100次,最终触发调用栈溢出错误;正常预期应仅执行if或else分支一次,Angular 17.0版本无此问题。- 当模板中同时存在
<app-header>、<app-project-navigation>和<router-outlet>时,即使跳过ngOnInit直接设置isDataLoaded = true,<app-header>和<app-project-navigation>仍会重复加载。
触发场景
仅当模板在同一个@defer(when isDataLoaded)块内同时包含以下三个元素时,会触发问题:
<app-header [project]="projectSignal()"></app-header> <app-project-navigation></app-project-navigation> <router-outlet></router-outlet>
即使简化getProject函数为直接设置isDataLoaded=true,无限循环问题依然存在:
private getProject(): void { console.log("test") this.isDataLoaded = true }
临时解决方案
以下方式可暂时规避问题:
- 将组件拆分到独立的
@defer块:
@defer(when isDataLoaded) { <app-header [project]="projectSignal()"></app-header> } @defer(when isDataLoaded) { <app-project-navigation></app-project-navigation> } @defer(when isDataLoaded) { @if(!hasErrorSignal()){ <router-outlet></router-outlet> } @else { <p>Error in making Http request(s).</p> } }
- 使用嵌套
@defer块包裹部分组件:
@defer(when isDataLoaded) { @if(!hasErrorSignal()){ @defer { <app-header [project]="projectSignal()"></app-header> } @defer { <app-project-navigation></app-project-navigation> } <router-outlet></router-outlet> } @else { <p>Error in making Http request(s).</p> } }
- 移除
@defer视图块,改用普通@if块替代 - 仅保留
<app-header>+<app-project-navigation>,或仅保留<router-outlet>
官方修复
Angular团队已确认这是17.3版本的变更检测Bug,并在发布后24小时内于Angular 17.3.2版本中完成修复,升级到该版本即可彻底解决问题。
内容的提问来源于stack exchange,提问作者Sachin
相关产品推荐
相关产品推荐

