私は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>
これが写真です:
テンプレート内の変数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>
もう少し読む必要があるだけで、* 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をオフにしておくので、真実になります。
この文書 私は構造的な指示を理解するのを助けました。
あなたが英雄チュートリアルの上手く書かれていない指示に従ったので、あなたはこのエラーを得ていました。私は同じことに遭遇しました。
具体的には、見出しテンプレート内のヒーロー名の表示の下に、次のように記載されています。
順不同のリストに英雄の名前を表示するには、タイトルの下と英雄の詳細の上に次の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>
これまでの取り組みから詳細要素がないことに注意してください。
作者によるこのようなエラーは、かなりワイルドなグースチェイスを引き起こす可能性があります。うまくいけば、この記事は他の人がそれを避けるのを助けます。
これを避けるために、コンポーネントのselectedHeroメンバを空のオブジェクトに初期化することもできます(未定義のままにすることはできません)。
あなたのサンプルコードでは、これは次のようになります。
export class AppComponent {
title = 'Tour of Heroes';
heroes = HEROES;
selectedHero:Hero = new Hero();
onSelect(hero: Hero):void{
this.selectedHero = hero;
}
}
この行
<h2>{{hero.name}} details!</h2>
*ngFor
の外側にあり、hero
がないため、hero.name
は失敗します。
これは私のために働いた:
export class Hero{
id: number;
name: string;
public Hero(i: number, n: string){
this.id = 0;
this.name = '';
}
}
そして、必ずselectedHeroも初期化してください。
selectedHero: Hero = new Hero();