web-dev-qa-db-ja.com

Angular 7エラーRangeError:最大呼び出しスタックサイズを超えました

公式チュートリアル( https://angular.io/tutorial/ )に従ってangularを学習しようとしていますが、ヒーローコンポーネントとヒーロー詳細コンポーネントの手順に従うと、エラー「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>

詳細については:

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

ヒーローコンポーネント

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コンポーネント

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

}

言及すべきことの1つは、<app-heroes></app-heroes>がコメント化されると、リストページがエラーなしでロードされることです。

Error message screenshot どんな助けもありがたい

9
Abdul Ali

1.このエラーは、無限ループがある場合に発生します。 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>

お役に立てれば。

7
Santhosh mp

この例では、自分の内部でコンポーネントをレンダリングするため、この操作を終了することはなく、常に別の子コンポーネントをレンダリングします(ブロックの2番目の部分が

更新-詳細:

コンポーネントを使用してアプリを作成する場合、すべてのコンポーネントは階層的であるため、同じコンポーネントをループ内の制限された量であることが確実な場合にのみ、自分の内部に含めることができます。コード例では、子コンポーネントが自分の体内で次の子コンポーネントを生成するため、無制限のネストされたコンポーネントがあります。結果として、ブラウザの表示エラー: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

<app-hero-detail>が詳細HTML内に表示されています。

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

これを削除してみてください。同様の行がhero.component.htmlでコメントされていますが、コメントを外すことができます。

1
Sachin Gupta

既存のアプリケーションをangular 8にアップグレードし、新しいルーティング機能を使用する場合、このエラーの別の原因を説明する回答を追加します。

私の場合、新しい構文を使用して、遅延ロードされた各ルートにdataオブジェクトをpreloadtrue || falseに設定して追加しました。

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

しかし、preloadingStrategy forRoot宣言でPreloadAllModulesRouterModuleに設定したままにしていたことに気付くまでに少し時間がかかりました。

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

モジュールforRoot宣言からpreloadingStrategyを削除し、ルートデータのプリロードdefinitioに依存することで問題が修正されます。

0
FRECIA