首页 > 解决方案 > 迁移到 Angular 12 后 Cytoscape.js“超出最大调用堆栈大小”错误

问题描述

最近,我将 Angular 应用程序从版本 10 迁移到 12。自从我迁移后,使用 cytoscape.js 可视化图形的组件产生以下错误:

ERROR RangeError: Maximum call stack size exceeded
at V.y.<computed>.get (polyfills.js:1)
at V.y.<computed>.get (polyfills.js:1)
at V.y.<computed>.get (polyfills.js:1)
at V.y.<computed>.get (polyfills.js:1)
at V.y.<computed>.get (polyfills.js:1)
at V.y.<computed>.get (polyfills.js:1)
at V.y.<computed>.get (polyfills.js:1)
at V.y.<computed>.get (polyfills.js:1)
at V.y.<computed>.get (polyfills.js:1)
at V.y.<computed>.get (polyfills.js:1)

当我通过像这样调用其构造函数来初始化 Cytoscape 时会发生此错误:

 this.cytoscape = cytoscape({
  container: document.getElementById('cytoscape-canvas-area'), //This line causes the error
  elements: {...initialGraph} as any,
  style: GRAPH_STYLES,
  layout: GRAPH_LAYOUT,
  autoungrabify: true,
  boxSelectionEnabled: true,
  panningEnabled: true,
  userPanningEnabled: true,
  userZoomingEnabled: true,
  zoomingEnabled: true,
  zoom: 1,
  minZoom: 0.1,
  maxZoom: 10,
});

在进行故障排除时,我发现只要我在代码中标记了上面示例中的行,就会发生错误。我已经检查过是否document.getElementById('cytoscape-canvas-area')返回了某些东西,就是这种情况。

这是我的 package.json 与所有版本:

 "dependencies": {
"@angular/animations": "~12.2.0",
"@angular/common": "~12.2.0",
"@angular/compiler": "~12.2.0",
"@angular/core": "~12.2.0",
"@angular/elements": "^12.2.0",
"@angular/forms": "~12.2.0",
"@angular/localize": "^12.2.0",
"@angular/platform-browser": "~12.2.0",
"@angular/platform-browser-dynamic": "~12.2.0",
"@angular/router": "~12.2.0",
"@fortawesome/angular-fontawesome": "^0.9.0",
"@fortawesome/fontawesome-svg-core": "^1.2.28",
"@fortawesome/free-solid-svg-icons": "^5.13.0",
"@fortawesome/pro-regular-svg-icons": "^5.15.3",
"@ngx-translate/core": "^13.0.0",
"@ngx-translate/http-loader": "^6.0.0",
"@types/cytoscape": "^3.14.17",
"@types/jest": "^26.0.24",
"angular-font-awesome": "^3.1.2",
"bootstrap": "^4.4.1",
"concurrently": "^5.1.0",
"cytoscape": "^3.19.1",
"cytoscape-canvas": "^3.0.1",
"cytoscape-cxtmenu": "^3.1.2",
"cytoscape-dagre": "^2.3.2",
"document-register-element": "^1.7.2",
"http-server": "^0.12.1",
"jest": "^27.0.6",
"jest-preset-angular": "^9.0.5",
"live-server": "^1.2.1",
"moment": "^2.26.0",
"ngx-bootstrap": "^5.3.2",
"ngx-build-plus": "^10.1.1",
"rxjs": "^6.6.0",
"tslib": "^2.3.0",
"zone.js": "~0.11.4" },

 "devDependencies": {
"@angular-devkit/build-angular": "~12.2.0",
"@angular/cli": "^12.2.0",
"@angular/compiler-cli": "~12.2.0",
"@angular/language-service": "~12.2.0",
"@types/node": "^12.11.1",
"codelyzer": "^6.0.0",
"cytoscape-edgehandles": "^3.6.0",
"ts-node": "~7.0.0",
"tslint": "~6.1.0",
"typescript": "~4.3.5"
},

如果有人可以帮助我,我会很高兴:)

更新 1

当我设置一个新的 Angular 12 应用程序并添加 Cytoscape.js 时,一切正常。该错误仅出现在此项目中。我使用 ng update 并遵循 Angular 的官方更新指南进行了迁移。不幸的是,我不能只使用一个新项目,因为这个项目正在生产中。

更新 2

this.cytoscape = cytoscape(...)ngOnChanges在我从远程服务器获取一些数据后在循环中调用。我已经检查了传递数据的结构,它是正确的。

this.graphService.getByUuidWithNodesAndEdges(uuid).subscribe(graphData => {
  this.cytoscapeService.createCanvas(graphData);
});

cytoscapeService是我自己创建的一个服务,它管理与框架相关的所有代码。

createCanvas(initialGraph: GraphCyo) {
   this.cytoscape = cytoscape({
     container: document.getElementById('cytoscape-canvas-area'),
     elements: {...initialGraph} as any,
     ...otherConfig
   });
}

更新 3

该错误与错误的 Angular Lifecycle Hook 或加载大量数据无关。当我在视图中添加一个按钮时也会出现相同的异常,该按钮会使用一些虚拟数据触发 cytoscape 的初始化:

<div style="background: #ffcc00; height: 500px; width: 500px" id="test-container-cy-bug">
<button style="position: fixed; left: 0; bottom: 0; z-index: 99" (click)="initCytoscapeCanvas()">Init!</button>

然后是init方法:

initCytoscapeCanvas() {
   this.cytoscape = cytoscape({
     container: document.getElementById('test-container-cy-bug'),
     elements: [
       {
         group: 'nodes',
         data: {
           id: '1'
         }
       },
       {
         group: 'nodes',
         data: {
           id: '2'
         }
       },
       {
         group: 'edges',
         data: {
           id: 'e',
           source: '1',
           target: '2'
         }
       }
     ]
   });
 }

单击Init!按钮时出现错误:

ERROR RangeError: Maximum call stack size exceeded
    at V.y.<computed>.get (polyfills.js:1)
    at V.y.<computed>.get (polyfills.js:1)
    at V.y.<computed>.get (polyfills.js:1)
    at V.y.<computed>.get (polyfills.js:1)
    at V.y.<computed>.get (polyfills.js:1)
    at V.y.<computed>.get (polyfills.js:1)
    at V.y.<computed>.get (polyfills.js:1)
    at V.y.<computed>.get (polyfills.js:1)
    at V.y.<computed>.get (polyfills.js:1)
    at V.y.<computed>.get (polyfills.js:1)
defaultErrorLogger  @   core.js:6479
handleError @   core.js:6527
handleError @   core.js:10938
executeListenerWithErrorHandling    @   core.js:15311
wrapListenerIn_markDirtyAndPreventDefault   @   core.js:15346
(anonymous) @   platform-browser.js:561
ZoneDelegate.invokeTask @   zone.js:421
onInvokeTask    @   core.js:28659
ZoneDelegate.invokeTask @   zone.js:420
Zone.runTask    @   zone.js:188
ZoneTask.invokeTask @   zone.js:503
invokeTask  @   zone.js:1671
globalZoneAwareCallback @   zone.js:1697

标签: angularstack-overflowcytoscape.jscytoscapezone

解决方案


推荐阅读