【问题标题】:Pushing data to an array in Angular 4 component from JSON从 JSON 将数据推送到 Angular 4 组件中的数组
【发布时间】:2018-01-29 23:39:01
【问题描述】:

所以,基本上,我试图在我的@987654322 中将每个艺术家的所有专辑添加到一个名为albums 的 JSON 文件中,包括嵌套专辑(我特别难处理) @。

我试图弄清楚和学习的整体解决方案是专门将每个专辑添加到一个数组中,以便我可以制作一个Albums 组件。此页面显示每张专辑,它们不与同一艺术家的其他专辑耦合。这样我就可以按字母顺序组织它们,等等。

希望我对这个问题有正确的思考过程!

不管怎样,代码如下:

这里是服务提供的数据,并被注入到组件(和其他组件)中。请注意,艺术家'Flume' 有两张专辑,而其他专辑只有一张(到目前为止)。

import { Injectable } from '@angular/core';

@Injectable()
export class DataService {

  constructor() { }

  data = {
    "artists": [
      {
        "artistName": "Lupe Fiasco",
        "artistsPicture": "../assets/artists-images/lupe.jpg",
        "genre": "Hip-Hop",
        "albums": [
          { "name": "Food & Liquor",
            "albumCover": "../assets/album-covers/f&l.jpg",
            "songs": {
              "name": "Kick, Push",
              "file": "mp3"
            }
          }
        ]
      },
      {
        "artistName": "Flume",
        "artistsPicture": "../assets/artists-images/flume.jpg",
        "genre": "",
        "albums": [
          { "name": "Flume",
            "albumCover": "../assets/album-covers/flume.jpg",
            "songs": {
              "name": "Sleepless",
              "file": "mp3"
            }
          },
          { "name": "Skin",
            "albumCover": "../assets/album-covers/skin.png",
            "songs": {
              "name": "Sleepless",
              "file": "mp3"
            }
          }
        ]
      },
      {
        "artistName": "Linkin Park",
        "artistsPicture": "../assets/artists-images/linkinpark.jpg",
        "genre": "",
        "albums": [
          { "name": "Hybrid Theory",
            "albumCover": "../assets/album-covers/meteora.jpg",
            "songs": {
              "name": "Sleepless",
              "file": "mp3"
            }
          }
        ]
      },
      {
        "artistName": "Drake",
        "artistsPicture": "../assets/artists-images/drake.jpg",
        "genre": "",
        "albums": [
          { "name": "Views",
            "albumCover": "../assets/album-covers/views.png",
            "songs": {
              "name": "Sleepless",
              "file": "mp3"
            }
          }
        ]
      },
      {
        "artistName": "J.Cole",
        "artistsPicture": "../assets/artists-images/jcole.jpg",
        "genre": "",
        "albums": [
          { "name": "2014 Forest Hills Drive",
            "albumCover": "../assets/album-covers/fhd.jpg",
            "songs": {
              "name": "Sleepless",
              "file": "mp3"
            }
          }
        ]
      },
      {
        "artistName": "Eminem",
        "artistsPicture": "../assets/artists-images/eminem.jpg",
        "genre": "",
        "albums": [
          { "name": "Marshal Matthers LP",
            "albumCover": "../assets/album-covers/mmlp.jpg",
            "songs": {
              "name": "Sleepless",
              "file": "mp3"
            }
          }
        ]
      },
    ]
  }


}

组件 HTML。这是启发这个问题的部分。当我这样循环时,两个'Flume' 专辑在 UI 中耦合在一起。 呜呜呜呜呜呜呜

因此它实现了显示每个专辑封面,但未能将它们与来自同一艺术家的其他专辑分开。

<div *ngFor='let x of artistData.artists'>
  <img *ngFor='let x of x.albums' src="{{x.albumCover}}" alt="">
</div>

所以我的解决方案是在将组件显示在 UI 中之前尝试在组件中对其进行排序。这是组件:

import { Component, OnInit } from '@angular/core';
import { DataService } from './../../data.service';

@Component({
  selector: 'app-albums',
  templateUrl: './albums.component.html',
  styleUrls: ['./albums.component.css']
})
export class AlbumsComponent implements OnInit {

  constructor(private dataService: DataService) { }

  artistData = this.dataService.data;

  albums: any[] = [];


  ngOnInit() {
    console.log(this.albums);

  }

}

【问题讨论】:

    标签: javascript arrays json angular for-loop


    【解决方案1】:

    您需要将各个专辑展平为单个数组,而不是艺术家对象内的嵌套数组。有几种可能的实现方式,这里我使用了Array.prototype.reduce()

    添加到组件逻辑

    const flatAlbums = data.artists.reduce((acc, next) => {
      next.albums.forEach(album => {
        acc.push(album);
      });
      return acc;
    }, []);
    

    console.log(flatAlbums) 的结果:

    [ { name: 'Food & Liquor',
        albumCover: '../assets/album-covers/f&l.jpg',
        songs: { name: 'Kick, Push', file: 'mp3' } },
      { name: 'Flume',
        albumCover: '../assets/album-covers/flume.jpg',
        songs: { name: 'Sleepless', file: 'mp3' } },
      { name: 'Skin',
        albumCover: '../assets/album-covers/skin.png',
        songs: { name: 'Sleepless', file: 'mp3' } },
      { name: 'Hybrid Theory',
        albumCover: '../assets/album-covers/meteora.jpg',
        songs: { name: 'Sleepless', file: 'mp3' } },
      { name: 'Views',
        albumCover: '../assets/album-covers/views.png',
        songs: { name: 'Sleepless', file: 'mp3' } },
      { name: '2014 Forest Hills Drive',
        albumCover: '../assets/album-covers/fhd.jpg',
        songs: { name: 'Sleepless', file: 'mp3' } },
      { name: 'Marshal Matthers LP',
        albumCover: '../assets/album-covers/mmlp.jpg',
        songs: { name: 'Sleepless', file: 'mp3' } } ]
    

    修改组件 HTML

    仅迭代新的flatAlbums 数组。

    <div *ngFor='let x of flatAlbums'>
      <img src="{{x.albumCover}}" alt="">
    </div>
    

    【讨论】:

    • 非常感谢 :D 我忘了 .reduce() 啊。
    • @EddieTaliaferroII 很高兴它对你有用。 .reduce() 可能是我在所有 JavaScript 中最喜欢的方法。令人难以置信的强大。
    • 我将从docs 示例开始。除了明显的部分之外,可选的第二个参数,在这种情况下:[](第一个参数,作为 reducer 函数)将acc 实例化为一个空数组。 next 只是在原始数组中找到的下一个值,因为它正在被迭代。此外,如果我没有提供第二个可选参数[],那么acc 会自动实例化为正在迭代的数组中的第一个值,next 从第二个值开始。有意义吗?
    • @EddieTaliaferroII 我花了很长时间潜心研究才明白.reduce()的强大。 Here 是我研究的公开回购,特别是 .reduce() 部分。当我说“强大”时,也许你会发现理解我的意思会有所帮助。
    • 再次感谢。这绝对是我游戏中的一个漏洞,今晚我将花一些时间研究这个,以便我能变得更好
    猜你喜欢
    • 2014-10-11
    • 2015-03-31
    • 1970-01-01
    • 2018-08-12
    • 1970-01-01
    • 2015-09-13
    • 1970-01-01
    • 2017-11-11
    • 1970-01-01
    相关资源
    最近更新 更多