Angular使用*ngFor渲染第三方EJS图表系列触发无限递归报错
问题诱因排查
首先排查代码中的明显笔误:
你在*ngFor中定义的循环变量是let serie of Values,但绑定dataSource时写成了serue.DetailValues,拼写错误会导致传入组件的数据源为undefined,Syncfusion的ej2组件内部处理空数据源的逻辑存在循环递归调用时,就会直接触发栈溢出。先修正为[dataSource]="serie.DetailValues"再测试。
如果修正拼写后问题仍存在,常见诱因如下:
- ngFor无trackBy导致组件频繁重建:默认Angular的ngFor通过对象引用判断数组元素是否变更,如果你的
Values数组在变更检测周期中反复生成新实例(比如通过getter每次返回新数组、接口拉取数据时反复重赋值整个数组),会导致e-series组件被不停销毁重建,ej2组件初始化时的对象深拷贝逻辑遇到循环引用就会触发递归溢出。可以给ngFor加上trackBy函数,用serie.Id作为唯一跟踪标识:
模板修改为:
组件ts文件中添加对应方法:<e-series *ngFor="let serie of Values; trackBy: trackBySerieId; let i = index" [dataSource]="serie.DetailValues" type="Line" xName="DateTime" yName="Value" [name]="serie.Id"> </e-series>trackBySerieId(index: number, serie: any): string { return serie.Id; } - 输入属性绑定不规范:你当前给name属性用的是插值语法
name={{serie.Id}},未使用标准属性绑定,Angular变更检测时会反复重写该属性值,触发e-series组件的输入变更钩子,反复执行内部重绘/对象拷贝逻辑,也可能诱发递归,改成[name]="serie.Id"的属性绑定写法即可。 - 数据存在循环引用:如果你的
serie对象本身存在循环引用(比如serie.DetailValues里的某个属性反向指向serie本身),ej2的extend深拷贝方法未对循环引用做兼容处理,就会陷入无限递归,这种情况需要手动清理数据中的循环引用再传给组件。
内容的提问来源于stack exchange,提问作者Marco Macchione
相关产品推荐
相关产品推荐

