5

JSON ファイルからデータを取得してフォームを作成しようとしています。

これが私のテンプレートの一部です:

  <div class="form-group">
    <label for="power">Power</label>
    <select class="form-control" id="power" required>
      <option *ngFor="let p of heroes" [value]="p.level">{{p.level}}</option>
    </select>
  </div>

リモート JSON ファイルの一部を次に示します。

{
    "data": [
        {
            "level": "newbie",
            "places": [
                {
                    "place": "earth",
                    "categories": [
                        {
                            "category": "human",
                            "values": [
                                ...

それは問題なく動作しnewbie、メニューに他の選択肢がありselectます。しかし、場所をループしたいので、html テンプレートを次のように編集します。

  <div class="form-group">
    <label for="power">Power</label>
    <select class="form-control" id="power" required>
      <option *ngFor="let p of heroes[0].places" [value]="p.place">{{p.place}}</option>
    </select>
  </div>

JSONファイルからデータを取得するために使用するサービスは次のとおりです。

@Injectable()
export class HeroService {
    private url = 'app/mockups/heroes.json';

    constructor(private http: Http) { }

    getHeroes(): Promise<Hero[]> {
        return this.http.get(this.url)
            .toPromise()
            .then(response => response.json().data as Hero[])
            .catch();
    }
}

そしてここにあるhero.component

export class HeroComponent implements OnInit {
    heroes: Hero[];

    constructor(private heroService: HeroService) { }

    ngOnInit():void {
        this.getHeroes();
}

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

しかし、「未定義のプロパティ '0' を読み取れません」というエラーが表示されます。

なんで?

4

3 に答える 3

5

私は問題を理解しました。データを非同期でフェッチしているため、このエラーが発生しました。Angular がバインドを解決しようとすると、最初のデータがまだ null であるためにheroes[0]失敗します。

heroesそこで、配列の初期化と「エルビス演算子」の使用に関する問題を解決しました。

heroes: Hero[];コンポーネントの代わりにheroes: Hero[] = [];

heroes[0]?.placesheroes[0].placeshtml テンプレートの代わりに。

于 2016-09-06T16:17:24.910 に答える
1

@Gunter Zochbauer のソリューションの代わりにheroes、適切な型の Array プロパティとして宣言できます。すべての属性を持つクラスがある場合、プロパティを次のheroesように宣言します。heroes

heroes:Array<Heroes> //Assuming class name is Heroes

そして、次のようにコンストラクターで初期化します。

constructor(){
...    
this.heroes=new Array<Heroes>();
}

ngFor ループでは、次のようにクラス属性にアクセスするだけです。

<option *ngFor="let p of heroes" [value]="p.place">{{p.place}}</option>

それが役に立てば幸い。

于 2016-09-06T08:35:02.250 に答える