Отображение вложенных объектов из файла JSON в Angular2

Изучение того, как отображать вложенные данные с помощью Angular 2. В Интернете есть много подобных вопросов, но я не видел ничего, разбитого на простой объект, за которым я мог бы следить и повторять.

У меня есть список, который показывает список героев JSON: Базовый список и подробности для Супермена и Бэтмена

Моя текущая цель — показать список аккаунтов выбранного героя.

Моя проблема заключается в коде, связанном со списком, в котором я хотел бы показать учетные записи на основе выбранного героя.

Мой JSON не работает, где я могу видеть вложенные детали, но я не могу включить этот уровень детализации в список.

герой-detail.component.html

<main class="col-sm-9">
    <div *ngIf="hero">
        <h2>{{hero.user[0].firstName}} {{ hero.user[0].lastName }}</h2>
        <div>
            <label>First Name: </label>
            <input [(ngModel)]="hero.user[0].firstName" placeholder="First Name">
        </div>
        <div>
            <label>Last Name: </label>
            <input [(ngModel)]="hero.user[0].lastName" placeholder="Last Name">
        </div>

        <ul class="list-group">
            <li class="list-group-item" *ngFor="let hero of heroes">
                <div *ngFor="let account of accounts">
                    {{ account[0].accountName }}
                </div>
            </li>
        </ul>
    </div>
</main>

герой-detail.component.ts

import { Component, Input } from '@angular/core';
import { Hero } from './hero';

@Component({
    selector: 'my-hero-detail',
    templateUrl: './heroes-detail.component.html'
})
export class HeroesDetailComponent {

    @Input()
    hero: Hero;

}

герой-component.html

<aside class="col-sm-3">
<div class="list-group">
    <button class="list-group-item" 
        *ngFor="let hero of heroes" 
        [class.selected]="hero === selectedHero" 
        (click)="onSelect(hero)">
        {{ hero.user[0].firstName }} {{ hero.user[0].lastName }}
    </button>
</div>
</aside>

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

Heroes.component.ts

import { Component, OnInit }    from '@angular/core';

import { Hero }             from './hero';
import { HeroService }      from './hero.service';

@Component({
    selector: 'app-heroes',
    templateUrl: './heroes.component.html',
    providers: [ HeroService ]
})
export class HeroesComponent implements OnInit {
    title = 'Tour of Heroes';

    heroes: Hero[];
    selectedHero: Hero;

    constructor(
        private heroService: HeroService) { }

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

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

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

}

mock-heroes.ts

import { Hero } from './hero';

export const HEROES: Hero[] = 
[
    {
        "heroId": 1001,
        "alias": "Superman",
        "user": [
            {
                "firstName": "Clark",
                "lastName": "Kent",
                "email": "[email protected]"
            }
        ],
        "accounts": [
            {
                accountNum: "1234567890",
                accountName: "Personal Checking",
                type: "checking",
                balance: 1500.00
            },
            {
                accountNum: "2345678901",
                accountName: "Personal Savings",
                type: "savings",
                balance: 2000.00
            }
        ]
    },
    {
        "heroId": 1002,
        "alias": "Batman",
        "user": [
            {
                "firstName": "Bruce",
                "lastName": "Wayne",
                "email": "[email protected]"
            }
        ],
        "accounts": [
            {
                accountNum: "1234567890",
                accountName: "Personal Checking",
                type: "checking",
                balance: 7500000.00
            },
            {
                accountNum: "2345678901",
                accountName: "Personal Savings",
                type: "savings",
                balance: 20000000.00
            }
        ]
    }
]

person Phil Jefferies    schedule 11.12.2016    source источник


Ответы (2)


Вы должны сделать так:

<ul class="list-group">
   <li class="list-group-item" *ngFor="let hero of heroes">
       <div *ngFor="let account of hero.accounts">
          {{ account[0].accountName }}
       </div>
   </li>
</ul>

Вы должны использовать второй *ngFor с hero.accounts и улучшить структуру своего шаблона, вы используете hero в верхнем элементе div, как вы это получаете:

<div *ngIf="hero">

Так проверить сначала на основе вашего требования. Надеюсь, это поможет вам.

person Avnesh Shakya    schedule 11.12.2016
comment
Спасибо за ответ Авнеш. Это не сработало для меня, и я не видел никакой ошибки. - person Phil Jefferies; 11.12.2016
comment
Удалите *ngIf="hero" сверху, у вас нет переменной hero в вашем компоненте, и используйте *ngFor в верхнем элементе для обхода всего. Не могу понять вашу структуру. - person Avnesh Shakya; 11.12.2016
comment
Просто добавил код, который добавляет ngIf на основе начальной страницы. Надеюсь, это поможет. - person Phil Jefferies; 11.12.2016
comment
Попробуйте вывести свой список <ul class="list-group">....</ul> за пределы контейнера <div *ngIf="hero">...</div> и посмотрите, работает ли он. - person Avnesh Shakya; 11.12.2016
comment
Я вынес ‹ul› за пределы div с помощью *ngIf=hero, поскольку видел, о чем вы думали, но для меня это ничего не изменило. Я не получаю ни ошибок командной строки, ни ошибок консоли. Однако код инспектора показывает привязки шаблона = {ng-reflect-ng-for-of: null } - person Phil Jefferies; 11.12.2016

Эта проблема была решена с помощью Elvis operator (?.) отсюда: Angular2 ngFor Iterating over JSON

герой.тс

export class Hero {
    id: number;
    name: string;
    firstName: string;
    lastName: string;
    accounts: Array<Account>;
}

export interface Account {
    bank: string;
    type: string;
    balance: number;
}

герои-detail.component.html

<main class="col-sm-9">
    <div *ngIf="hero">
        <h2>{{hero.firstName}} {{ hero.lastName }}</h2>
        <div>
            <label>id: </label>{{hero.id}}
        </div>
        <div>
            <label>First Name: </label>
            <input [(ngModel)]="hero.firstName" placeholder="First Name">
        </div>
        <div>
            <label>Last Name: </label>
            <input [(ngModel)]="hero.lastName" placeholder="Last Name">
        </div>

        <table class="table table-hover">
            <thead>
                <tr>
                    <th>Bank Name</th>
                    <th>Account Type</th>
                    <th>Balance</th>
                </tr>
            </thead>
            <tbody>
                <tr *ngFor="let account of hero?.accounts">
                    <td>{{ account.bank }}</td>
                    <td>{{ account.type }}</td>
                    <td>{{ account.balance }}</td>
                </tr>
            </tbody>
        </table>
    </div>
</main>

mock-heroes.ts

import { Hero } from './hero';

export const HEROES: Hero[] = 
[
    {
        "id": 11, 
        "name": "Superman",
        "firstName": "Clark",
        "lastName": "Kent",
        "accounts": [
            {
                "bank": "Chase",
                "type": "Checking",
                "balance": 1000.00
            },
            {
                "bank": "Chase",
                "type": "Savings",
                "balance": 2000.00
            }
        ]
    },
    {
        "id": 12, 
        "name": "Batman",
        "firstName": "Bruce",
        "lastName": "Wayne",
        "accounts": [
            {
                "bank": "Bank of Gotham",
                "type": "Checking",
                "balance": 1000000000.00
            },
            {
                "bank": "Bank of Gotham",
                "type": "Savings",
                "balance": 2000000000.00
            }
        ]
    },
    {
        "id": 13, 
        "name": "Wonder Woman",
        "firstName": "Diana",
        "lastName": "Prince",
        "accounts": [
            {
                "bank": "",
                "type": "",
                "balance": 0.00
            },
            {
                "bank": "",
                "type": "",
                "balance": 0.00
            }
        ]
    }
]
person Phil Jefferies    schedule 12.12.2016