web-dev-qa-db-fra.com

Angular 7 error RangeError: La taille maximale de la pile d'appels a été dépassée

j'essaie d'apprendre angular en suivant le tutoriel officiel ( https://angular.io/tutorial/ ), mais lorsque vous suivez les étapes pour le composant héros et le composant de détail du héros, cela génère une erreur " RangeError: taille maximale de la pile d'appels dépassée ".

le hero.component.html et le code de détail est comme ci-dessous:

<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>

pour le détail:

<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>

composante de héros

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;
  }

}

composant hero.detail

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() {
  }

}

une chose à mentionner est que lorsque <app-heroes></app-heroes> est commenté, la page de liste est chargée sans erreur

Error message screenshot toute aide appréciée

9
Abdul Ali

1. Cette erreur se produit lorsqu'il y a une boucle infinie. Comme vous l'avez mentionné, la page se charge lorsque app-heroes est commenté, il peut être utilisé comme nom de sélecteur pour plus d'un composant, ce qui n'est pas autorisé. Cela peut provoquer une boucle infinie et empêcher le chargement des composants.

  1. Essayez de faire les modifications ci-dessous,

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>

J'espère que cela t'aides.

7
Santhosh mp

Dans votre exemple, vous rendez le composant à l’intérieur de vous-même, de sorte que vous ne finissiez jamais cette opération et restituiez toujours un autre composant enfant (si la deuxième partie du bloc est

Mise à jour - plus de détails:

Si vous écrivez app avec des composants, tous les composants sont hiérarchiques, vous pouvez donc inclure le même composant en vous-même uniquement si vous êtes sûr que le nombre de boucles est limité. Dans votre exemple de code, vous avez un nombre illimité de composants imbriqués, car le composant enfant génère le prochain composant enfant dans votre corps. Il en résulte une erreur d'affichage de votre navigateur: 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>

app-hero-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>
2
kris_IV

Tu as le <app-hero-detail> affiché dans les détails HTML.

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

S'il vous plaît essayez d'enlever ceci. Une ligne similaire est commentée dans le hero.component.html, vous pouvez décommenter cela.

1
Sachin Gupta

J'ajouterai une réponse décrivant une cause différente de cette erreur lors de la mise à niveau vers angular 8 une application existante et à l'aide de nouvelles fonctionnalités de routage.

Dans mon cas, j’ai ajouté à chaque itinéraire chargé paresseux l’objet data avec preload défini sur true || false en utilisant la nouvelle syntaxe:

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

Cependant, il m'a fallu un certain temps pour réaliser que j'avais laissé l'ensemble preloadingStrategy défini sur PreloadAllModules dans ma déclaration RouterModule forRoot:

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

La suppression de preloadingStrategy du module pour la déclaration Racine et le recours à la définition du préchargement des données de route résolvent le problème.

0
FRECIA