从Angular 2中的JSON对象获取嵌套数据

时间:2016-10-04 21:19:31

标签: json angular typescript

您好我正在构建类似于音乐播放器应用的东西。我有一个服务设置从我在一个夹具中的JSON文件中获取数据。我可以使用* ngFor获取所有顶级数据,但是一旦我开始要求像songs.parts.name那样显示未定义的内容。

我有* ngFor在页面上吐出顶级键值对,然后我希望能够点击特定歌曲名称并让它过滤数据以找到正确的歌曲URL。

如何遍历该数组并获取这些对象?

非常感谢任何帮助。

JSON

{
  "songs": [
    {
      "name": "America The Beautiful",
      "difficulty": "Medium",
      "time": "3:38",
      "hasPianoWords": true,
      "hasPianoSolfa": false,
      "hasTrackWords": false,
      "parts": [
        {
          "name": "Baritone",
          "urls": {
            "pianoWords": "http://www.taabc.org/check-off-songs/baritone/america-the-beautiful/america-the-beautiful-piano-words.mp3",
            "pianoSolfa": "http://www.taabc.org/check-off-songs/baritone/america-the-beautiful/america-the-beautiful-piano-words.mp3",
            "trackWords": "http://www.taabc.org/check-off-songs/baritone/america-the-beautiful/america-the-beautiful-piano-words.mp3"
          }
        },
        {
          "name": "Bass",
          "urls": {
            "pianoWords": "http://www.taabc.org/check-off-songs/bass/america-the-beautiful/america-the-beautiful-piano-words.mp3",
            "pianoSolfa": "http://www.taabc.org/check-off-songs/bass/america-the-beautiful/america-the-beautiful-piano-words.mp3",
            "trackWords": "http://www.taabc.org/check-off-songs/bass/america-the-beautiful/america-the-beautiful-piano-words.mp3"
          }
        },
        {
          "name": "Second Tenor",
          "urls": {
            "pianoWords": "http://www.taabc.org/check-off-songs/second-tenor/america-the-beautiful/america-the-beautiful-piano-words.mp3",
            "pianoSolfa": "http://www.taabc.org/check-off-songs/second-tenor/america-the-beautiful/america-the-beautiful-piano-words.mp3",
            "trackWords": "http://www.taabc.org/check-off-songs/second-tenor/america-the-beautiful/america-the-beautiful-piano-words.mp3"
          }
        },
        {
          "name": "First Tenor",
          "urls": {
            "pianoWords": "http://www.taabc.org/check-off-songs/first-tenor/america-the-beautiful/america-the-beautiful-piano-words.mp3",
            "pianoSolfa": "http://www.taabc.org/check-off-songs/first-tenor/america-the-beautiful/america-the-beautiful-piano-words.mp3",
            "trackWords": "http://www.taabc.org/check-off-songs/first-tenor/america-the-beautiful/america-the-beautiful-piano-words.mp3"
          }
        }
      ]
    }
  ]
}

Songs.Service.ts

export class SongService {
    constructor(private _http: Http) {}

    getAllSongs() {
        return this._http.get('/fixtures/songs.json')
            .map((response: Response) => response.json().songs)
            .toPromise()
            .catch(this.handleError);
    }

    getSongByName(songName:string) {
        return this._http.get('/fixtures/songs.json')
            .map((response: Response) => _.find(response.json().songs, {'name': songName}))
            .toPromise()
            .catch(this.handleError);
    }

歌曲组件

export class SongsComponent {
    public songs: any;
    public activeSong: any;
    public activeSongURL: any;

    constructor(private _songsService: SongService, private router: Router, private route: ActivatedRoute) {
    }

    ngOnInit() {
        this._songsService.getAllSongs().then(result => {
            this.songs = result;
            console.log('Songs: ', this.songs);
        });
    }

    playSong(songName:string) {
        console.log('clicked song:', songName)

        this._songsService.getSongByName(songName).then(result => {
            this.activeSong = result;
            console.log('active song', this.activeSong);
            this.activeSongURL = this.activeSong.baritone.pianoWords;
            console.log(this.activeSongURL);
        })
    }

    selectSong(songName:string) {
        this.router.navigate(['/song'], songName);
    }
}

HTML模板

<section class="songs container">
    <div class="song col-md-3" *ngFor="let song of songs">
        <h4 (click)="selectSong(song.name)">{{song.name}}</h4>
        <span>Difficulty: {{song.difficulty}}</span>
        <span>Time: {{song.time}}</span>
        <span><strong>Baritone</strong></span>
        <span *ngIf="song.hasPianoSolfa" class="piano-solfa"><i class="fa fa-play-circle-o" aria-hidden="true"></i>Piano Solfa</span>
        <span (click)="playSong(song.name)" *ngIf="song.hasPianoWords" class="piano-words"><i class="fa fa-play-circle-o" aria-hidden="true"></i>Piano Words</span>
        <span (click)="playSong(song.name)" *ngIf="song.hasTrackWords" class="track-words"><i class="fa fa-play-circle-o" aria-hidden="true"></i>Track Words</span>
    </div>
</section>

<section class="audio-player">
    <audio src="{{activeSongURL}}" autoplay controls="controls">
        Your browser does not support the <code>audio</code> element.
    </audio>
</section>

1 个答案:

答案 0 :(得分:2)

您可以使用Safe-Navigation-Operator

看起来你可能已经拥有它或接近拥有它,不应该像是

<section class="songs container">
    <div class="song col-md-3" *ngFor="let song of songs">
        <h4 (click)="selectSong(song.name)">{{song.name}}</h4>
        <span>Difficulty: {{song.difficulty}}</span>
        <span>Time: {{song.time}}</span>

        <div *ngIf="song?.parts.length > 0">

            <div *ngFor="let part of song?.parts">
                <strong>{{ part.name }}</strong>
                <span class="piano-words" (click)="playSong(song.name)"><i class="fa fa-play-circle-o" aria-hidden="true"></i>Piano Words</span>
                <span class="piano-solfa" (click)="playSong(song.name)"><i class="fa fa-play-circle-o" aria-hidden="true"></i>Piano Solfa</span>
                <span class="track-words" (click)="playSong(song.name)"><i class="fa fa-play-circle-o" aria-hidden="true"></i>Track Words</span>
            </div>

        </div>

        <!-- <span><strong>Baritone</strong></span>
        <span *ngIf="song.hasPianoSolfa" class="piano-solfa"><i class="fa fa-play-circle-o" aria-hidden="true"></i>Piano Solfa</span>
        <span (click)="playSong(song.name)" *ngIf="song.hasPianoWords" class="piano-words"><i class="fa fa-play-circle-o" aria-hidden="true"></i>Piano Words</span>
        <span (click)="playSong(song.name)" *ngIf="song.hasTrackWords" class="track-words"><i class="fa fa-play-circle-o" aria-hidden="true"></i>Track Words</span>
    </div> -->
</section>