Angular 7 error RangeError: Maximum call stack size exceeded

Angular 7 error RangeError: Maximum call stack size exceeded

我正在尝试通过遵循 official tutorial 来学习 angular,但是当遵循 hero componenthero detail component 的步骤时,它会引发错误“RangeError:最大调用堆栈超出尺寸。

hero.component.html:

<ul class="heroes">
  <li *ngFor="let hero of heroes" (click)="onSelect(hero)" [class.selected]="hero === selectedHero">
    <span class="badge">{{hero.id}}</span> {{hero.name}}
  </li>
</ul>

<!-- 
<app-hero-detail [hero]="selectedHero"></app-hero-detail> -->


<app-heroes></app-heroes>

detail component:

<div *ngIf="hero">

  <h2>{{hero.name}} Details</h2>
  <div><span>id: </span>{{hero.id}}</div>
  <div>
    <label>name:
      <input [(ngModel)]="hero.name" placeholder="name"/>
    </label>
  </div>

</div>

<app-hero-detail [hero]="selectedHero"></app-hero-detail>

hero component

import { Component, OnInit } from '@angular/core';
import { Hero } from '../hero';
import { HEROES } from '../mock-heroes';
import { HeroService } from '../hero.service';

@Component({
  selector: 'app-heroes',
  templateUrl: './heroes.component.html',
  styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit {
  heroes: Hero[];

  selectedHero: Hero;

  constructor(private heroService: HeroService) { }

  ngOnInit() {
    this.getHeroes();
  }

  getHeroes(): void {
    this.heroes = this.heroService.getHeroes();
  }

  onSelect(hero: Hero): void {
    this.selectedHero = hero;
  }

}

hero.detail component

import { Component, OnInit, Input } from '@angular/core';
import { Hero } from '../hero';

@Component({
  selector: 'app-hero-detail',
  templateUrl: './hero-detail.component.html',
  styleUrls: ['./hero-detail.component.css']
})
export class HeroDetailComponent implements OnInit {

  @Input() hero: Hero;
  constructor() { }

  ngOnInit() {
  }

}

值得一提的是,当<app-heroes></app-heroes>被评论时,列表页面加载没有错误

任何帮助表示赞赏

1.This 死循环时出现错误。 正如您所提到的,当评论 app-heroes 时页面加载,这可能被用作多个组件的选择器名称,即不允许。 这可能会导致无限循环并无法加载组件。

  1. 尝试进行以下编辑,

hero.component.html

<ul class="heroes">
  <li *ngFor="let hero of heroes" (click)="onSelect(hero)" [class.selected]="hero === selectedHero">
    <span class="badge">{{hero.id}}</span> {{hero.name}}
  </li>
</ul>

<app-hero-detail [hero]="selectedhero"></app-hero-detail> 

hero.detail.component.html

<div *ngIf="hero">
  <h2>{{hero.name}} Details</h2>
  <div><span>id: </span>{{hero.id}}</div>
  <div>
    <label>name:
      <input [(ngModel)]="hero.name" placeholder="name"/>
    </label>
  </div>
</div>

希望对您有所帮助。

在您的示例中,您在自己内部渲染组件,因此您永远不会完成此操作并且始终渲染另一个子组件(如果块的第二部分是

更新 - 更多详情:

如果您使用组件编写应用程序,所有组件都是分层的,因此只有当您确定内部循环数量有限时,您才可以在自己内部包含相同的组件。在您的代码示例中,您有无限的嵌套组件,因为子组件会在您体内生成下一个子组件。结果您的浏览器显示错误:RangeError: Maximum call stack size exceeded

hero.component.html

<ul class="heroes">
  <li *ngFor="let hero of heroes" (click)="onSelect(hero)" [class.selected]="hero === selectedHero">
    <span class="badge">{{hero.id}}</span> {{hero.name}}
  </li>
</ul>

<!-- 
<app-hero-detail [hero]="selectedHero"></app-hero-detail> -->


<app-heroes></app-heroes>

应用英雄-details.component.html

<div *ngIf="hero">

  <h2>{{hero.name}} Details</h2>
  <div><span>id: </span>{{hero.id}}</div>
  <div>
    <label>name:
      <input [(ngModel)]="hero.name" placeholder="name"/>
    </label>
  </div>

</div>

// you should comment line below
// <app-hero-detail [hero]="selectedHero"></app-hero-detail>

您在详细信息 HTML 中显示了 <app-hero-detail>

<app-hero-detail [hero]="selectedHero"></app-hero-detail>

请尝试删除它。 hero.component.html 中注释了类似的行,您可以取消注释。

我将添加一个答案,描述升级到 angular8 现有应用程序并使用新的路由功能时导致此错误的不同原因。

在我的例子中,我使用新语法向每个​​延迟加载路由添加了 data 对象,其中 preload 设置为 true || false

  {
    path: '',
    loadChildren: () => import('./views/home/home.module').then(mod => mod.HomeModule),
    data: { preload: true }
  },

但是我花了一段时间才意识到我在 RouterModule forRoot 声明中将 preloadingStrategy 设置为 PreloadAllModules

@NgModule({
  imports: [RouterModule.forRoot(
    routes,
    {
      preloadingStrategy: PreloadAllModules, <-- This is the cause
    })],
    ...

从模块 forRoot 声明中删除 preloadingStrategy 并依赖路由数据预加载定义解决了这个问题。

升级到 angular8 现有应用程序并在单独的文件中使用新的路由功能时出现此错误的不同原因。

在我的例子中,没有将 featureRouterModule 导入其特定的 featureModule.ts 导致最大堆栈超过 error.Since angular 无法找到其特定的路由器文件注册

我在创建模块时能够重现此错误消息,但我忘记添加 RoutingModule。

@NgModule({
  declarations: [
  SuccessComponent,
  CheckoutComponent
],
  imports: [
    ShareModule,
    PaymentRoutingModule // Forget to add it.
  ]
})
export class PaymentModule { }

我不知道为什么会出现这个错误,但也许其他人也会犯同样的错误。

当我的 intellisense 不小心将模块名称(而不是特定组件名称)添加到模块的导出时,我正在处理这个错误:

@NgModule({
  declarations: [
    FooComponent,
    // ...
  ],
  imports: [CommonModule],
  exports: [
    FooModule, // <== should be 'FooComponent'
    // ...
  ], 
})
export class FooModule {}

不过,如果错误能够更具描述性,那肯定会很好,因为这个工具我有一段时间了

我把两个模块命名的差不多,没注意导入的是哪个。 如果您在自身内部导入模块,它将导致循环导入,直到达到最大调用堆栈。

这个错误是我在Angular 9.

错误的使用循环模块导入导致的
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
@NgModule({
 imports: [
    CommonModule,
    ModuleTwo
  ],
 
})
export class ModuleOne {
}

import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
    @NgModule({
    imports: [
        CommonModule,
        ModuleOne
      ],
     
    })
    export class ModuleTwo {
    }

我发现的此错误的可能情况:

  • 2 个或更多同名模块
  • 您的 app.module.ts 文件中导入错误
  • 编译有问题

您可以尝试的解决方案:

  • 对于第 1 点,更改名称并使它们独一无二
  • 对于第 2 点,确保所有导入都是按照您的模块用例进行的,请检查模块之间的 inter-dependency
  • 对于第 3 点,很少见,但如果浏览器没有足够的内存来处理,就会发生这种情况,因此请尝试重新启动您的代码编辑器、浏览器或您的 PC。

这发生在我订阅 observable 的频率超过要求时。我在每次按下 Enter 键时都订阅了以下可观察到的内容,

this.filteredOptions.subscribe((res) => this.addSelectedContacts(event, res[keyManager.activeItemIndex]))

这显然不是必需的,我不得不通过添加 pipe(take(1)) as,

来限制 observable 只获得第一个发射
this.filteredOptions.pipe(take(1)).subscribe((res) => this.addSelectedContacts(event, res[keyManager.activeItemIndex]))

您也可以使用 swithMap 运算符语法来关闭以前的订阅。