Angular 8运行报RangeError栈溢出错误,Dashboard页面无法加载、进度条不显示
栈溢出错误根因
- 错误根源是组件配置错配导致的无限递归渲染:
- 你将自定义进度条的选择器、Dashboard组件的类定义、页面模板的指向完全混写在了一起:当前带
@Component装饰器的类,选择器配置为app-progress-bar,但模板路径直接指向了dashboard.component.html——而dashboard.component.html内部又使用了<app-progress-bar>标签引用自身。 - 渲染时会形成死循环:应用加载Dashboard组件→读取
dashboard.component.html模板→识别到<app-progress-bar>标签→渲染该选择器对应的组件→再次读取dashboard.component.html模板→再次识别到<app-progress-bar>... 循环直到栈内存耗尽,抛出Maximum call stack size exceeded错误。
- 你将自定义进度条的选择器、Dashboard组件的类定义、页面模板的指向完全混写在了一起:当前带
- 额外存在两个逻辑隐患:
- 原本的进度条计算逻辑直接覆写了
@Input()传入的原始progress值,后续如果需要展示原始进度数据会出现异常 - 缺少进度条本身的展示HTML结构,就算不触发递归,也无法正常渲染进度条
- 原本的进度条计算逻辑直接覆写了
修复步骤
1. 拆分独立组件,修正装饰器配置
将原本混写的代码拆分为两个独立组件,避免模板引用自循环:
- 调整Dashboard组件的装饰器配置,匹配自身页面的选择器和模板:
// dashboard.component.ts import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-dashboard', // 对应页面路由的组件选择器,不要和进度条重名 templateUrl: './dashboard.component.html' }) export class DashboardComponent implements OnInit { ngOnInit() {} }
- 抽离独立的进度条组件,配置专属的选择器和模板路径:
// progress-bar.component.ts import { Component, OnInit, Input } from '@angular/core'; @Component({ selector: 'app-progress-bar', templateUrl: './progress-bar.component.html' // 指向进度条自身的模板,禁止引用dashboard页面模板 }) export class ProgressBarComponent implements OnInit { @Input() progress: number; @Input() total: number; color: string; displayPercent: number; // 独立存储计算后的进度百分比,避免污染入参值 ngOnInit() { // 原有业务逻辑保留 if(!this.progress) { this.progress = 0; } if(this.total === 0) { this.total = this.progress; } else if(!this.total) { this.total = 100; } if(this.progress > this.total) { this.progress = 100; this.total = 100; } // 计算后的百分比存入独立变量 this.displayPercent = (this.progress / this.total) * 100; if(this.displayPercent < 55) { this.color = 'red'; } else if(this.displayPercent < 75) { this.color = 'yellow'; } else { this.color = 'green'; } } }
2. 补充进度条专属的展示模板
新建progress-bar.component.html,编写进度条的实际渲染结构:
<div class="progress-wrapper" style="width: 100%;"> <div class="progress-track" [style.width.%]="displayPercent" [style.background]="color" style="height: 20px; border-radius: 4px; line-height: 20px; color: #fff; text-align: right; padding-right: 8px; box-sizing: border-box;" > </div> <div style="margin-top: 8px; text-align: center;"> {{ displayPercent | number: '1.0-0' }}% </div> </div>
3. 模块声明校验
在Dashboard所属功能模块的declarations数组中,同时加入DashboardComponent和ProgressBarComponent,确保Angular可以正确识别模板中使用的<app-progress-bar>标签。
验证效果
完成调整后启动应用,栈溢出报错会消失,页面正常加载,传入[progress]="10" [total]="100"时,进度条会渲染为10%宽度的红色进度,显示对应百分比数值。
内容的提问来源于stack exchange,提问作者arriff
相关产品推荐
相关产品推荐

