web-dev-qa-db-ja.com

Angular 2:未定義のプロパティ 'name'を読み取れません

私はAngular 2を学び始めています。私はangular.ioで提供されている英雄のチュートリアルに従ってきました。テンプレートを使用しているHTMLの混乱に悩まされるまで、私はその代わりにテンプレートURLを使用して、そのHTMLをhero.htmlという名前のファイルに移動するまで、すべてがうまくいきました。生成されるエラーは、「未定義のプロパティ 'name'を読み取れません」です。奇妙なことに、ngForが配列内のオブジェクトの数に従って正しい量の "li"タグを生成するように、オブジェクトの配列を指すheroes変数にアクセスすることができます。ただし、配列のオブジェクトのデータにアクセスすることはできません。さらに、テキストを保持する単純な変数であっても、HTMLの{{}}括弧を使用して表示されません(提供されているコードを参照)。

app.component.ts

import { Component } from '@angular/core';
@Component({
  selector: 'my-app',
  templateUrl: './hero.html',
  styleUrls:['./styles.css']
})

export class AppComponent {
  title = 'Tour of Heroes';
  heroes = HEROES;
  selectedHero:Hero;

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

export class Hero{
   id: number;
   name: string;
}

const HEROES: Hero[] = [
   { id: 1, name: 'Mr. Nice' },
   { id: 2, name: 'Narco' },
   { id: 3, name: 'Bombasto' },
   { id: 4, name: 'Celeritas' },
   { id: 5, name: 'Magneta' },
   { id: 6, name: 'RubberMan' },
   { id: 7, name: 'Dynama' },
   { id: 8, name: 'Dr IQ' },
   { id: 9, name: 'Magma' },
   { id: 10, name: 'Tornado' }
];

hero.html

<h1>{{title}}</h1>
<h2>My Heroes</h2>
<ul class="heroes">
  <li *ngFor="let hero of heroes">
    <span class="badge">{{hero.id}}</span> {{hero.name}}
  </li>
</ul>
<h2>{{hero.name}} details!</h2>
<div>
    <label>id: </label>{{hero.id}}
</div>
<div>
    <label>name: </label>
    <input [(ngModel)]="selectedHero.name" placeholder="name">
<div>

これが写真です:

enter image description here

50
user4431744

テンプレート内の変数selectedHeroはnullなので、selectedHero.nameをそのままバインドすることはできません。この場合はelvis演算子を使う必要があります。

<input [ngModel]="selectedHero?.name" (ngModelChange)="selectedHero.name = $event" />

[ngModel]と(ngModelChange)の[(ngModel)]を分離する必要もあります。これは、elvis演算子を使用する式に代入できないためです。

また、私はあなたが使うつもりであると思います:

<h2>{{selectedHero?.name}} details!</h2>

の代わりに:

<h2>{{hero.name}} details!</h2>
109

もう少し読む必要があるだけで、* ngIf構造ディレクティブが紹介されたはずです。

ユーザーがまだヒーローを選択していないため、selectedHero.nameはまだ存在していないため、undefinedが返されます。

<div *ngIf="selectedHero">
  <h2>{{selectedHero.name}} details!</h2>
  <div><label>id: </label>{{selectedHero.id}}</div>
  <div>
    <label>name: </label>
    <input [(ngModel)]="selectedHero.name" placeholder="name"/>
  </div>
</div>

* ngIfディレクティブは、それが選択されるまでDOMからselectedHeroをオフにしておくので、真実になります。

この文書 私は構造的な指示を理解するのを助けました。

23
Tom

あなたが英雄チュートリアルの上手く書かれていない指示に従ったので、あなたはこのエラーを得ていました。私は同じことに遭遇しました。

具体的には、見出しテンプレート内のヒーロー名の表示の下に、次のように記載されています。

順不同のリストに英雄の名前を表示するには、タイトルの下と英雄の詳細の上に次のHTMLのチャンクを挿入します。

このコードブロックが続きます:

<h2>My Heroes</h2>
<ul class="heroes">
  <li>
    <!-- each hero goes here -->
  </li>
</ul>

以前の詳細コードを置き換えるように指示するわけではありません。これが私たちが残されている理由です。

<h2>{{hero.name}} details!</h2>

*ngForの外側です。

ただし、ページをさらに下にスクロールすると、次のようになります。

ヒーローを表示するためのテンプレートは次のようになります。

<h2>My Heroes</h2>
<ul class="heroes">
  <li *ngFor="let hero of heroes">
    <span class="badge">{{hero.id}}</span> {{hero.name}}
  </li>
</ul>

これまでの取り組みから詳細要素がないことに注意してください。

作者によるこのようなエラーは、かなりワイルドなグースチェイスを引き起こす可能性があります。うまくいけば、この記事は他の人がそれを避けるのを助けます。

5
Josh Cronkhite

これを避けるために、コンポーネントのselectedHeroメンバを空のオブジェクトに初期化することもできます(未定義のままにすることはできません)。

あなたのサンプルコードでは、これは次のようになります。

export class AppComponent {
  title = 'Tour of Heroes';
  heroes = HEROES;
  selectedHero:Hero = new Hero();

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

この行

<h2>{{hero.name}} details!</h2>

*ngForの外側にあり、heroがないため、hero.nameは失敗します。

2

これは私のために働いた:

export class Hero{
   id: number;
   name: string;

   public Hero(i: number, n: string){
     this.id = 0;
     this.name = '';
   }
 }

そして、必ずselectedHeroも初期化してください。

selectedHero: Hero = new Hero();
0
grenny