web-dev-qa-db-fra.com

Accès au JSON imbriqué avec AngularJS

J'essaie de créer une application Web mobile avec angular.js, hammer.js et topcoat.

J'ai des problèmes pour afficher les données d'un fichier Json comme celui-ci:

{
"version": "1",
"artists": {
    "artist1": {
        "name": "artist1name",
        "jpeg": "../img/artist/artist1.jpg",
        "albums": {
            "album1": {
                "type": "cd",
                "title": "titlealbum1",
                "subtitle": "subtitlealbum1",
                "jpeg": "../img/album1.jpg",
                "price": "12.00",
                "anystring1": "anystring1album1",
                "anystring2": "anystring2album1"
            },
            "album2": [{
                "type": "cd",
                "title": "titlealbum2",
                "subtitle": "subtitlealbum2",
                "jpeg": "../img/album2.jpg",
                "price": "12.00",
                "anystring1": "anystring1album2",
                "anystring2": "anystring2album2"
            }],
            "album3": [{
                "type": "cd",
                "title": "titlealbum3",
                "subtitle": "subtitlealbum3",
                "jpeg": "../img/album3.jpg",
                "price": "13.00",
                "anystring1": "anystring1album3",
                "anystring2": "anystring2album3"
            }]
        }
    },
    "artist2": {
        "name": "artist2name",
        "jpeg": "../img/artist/artist2.jpg",

Mon fichier js est comme ça:

angular.module('list', [])
function ListCtrl ($scope, $http) {
$http({method: 'GET', url: 'json/json_price_1.json'}).success(function(data)
{
$scope.artists = data.artists; // response data 
$scope.albums = data.artists.albums; /this is where im getting trouble
});        
};

Mon fichier HTML ressemble à ceci:

<body ng-app="list">

<h3>Titulos</h3>

<div ng-controller="ListCtrl">
<ul ng-repeat="artist in artists">
        <li >{{artist.name}}</li>

    </ul>
</div>

<div ng-controller="ListCtrl">
<ul ng-repeat="album in albums">
        <li >{{album.title}}</li>  //not working here. 

    </ul>
</div>

Je souhaite afficher tous les albums et si mon utilisateur sélectionne un artiste spécifique, je souhaite filtrer ces albums ..___ La question est de savoir comment je sélectionnerai ce fichier imbriqué. Au fait, le nom d'artiste s'affiche correctement.

La deuxième question est, comment vais-je filtrer ces artistes avec un champ de texte. 

21
scarface13

Je suggère quelque chose comme ça:

$http({method: 'GET', url: 'json/json_price_1.json'}).success(function(data) {
    $scope.artists = [];
    angular.forEach(data.artists, function(value, key) {
        $scope.artists.Push(value);
    });
    $scope.isVisible = function(name){
        return true;// return false to hide this artist's albums
    };
});

Et alors:

<div ng-controller="ListCtrl">
    <ul>
        <li ng-repeat="artist in artists">{{artist.name}}</li>
    </ul>
    <ul ng-repeat="artist in artists" ng-show="isVisible(artist.name)">
        <li ng-repeat="album in artist.albums">{{album.title}}</li>
    </ul>
</div>
13
Adam

Tous vos problèmes commencent avec votre JSON. Je vous recommande de simplifier votre code JSON et de faire en sorte que chaque tableau Artist et Album soit un objet et les tableaux Artists et Albums

Essaye celui-là:


{
  "version": "1",
  "artists": [
    {
      "name": "artist1name",
      "jpeg": "../img/artist/artist1.jpg",
      "albums": [
        {
          "type": "cd",
          "title": "titlealbum1",
          "subtitle": "subtitlealbum1",
          "jpeg": "../img/album1.jpg",
          "price": "12.00",
          "anystring1": "anystring1album1",
          "anystring2": "anystring2album1"
        },
        {
          "type": "cd",
          "title": "titlealbum2",
          "subtitle": "subtitlealbum2",
          "jpeg": "../img/album2.jpg",
          "price": "12.00",
          "anystring1": "anystring1album2",
          "anystring2": "anystring2album2"
        },
        {
          "type": "cd",
          "title": "titlealbum3",
          "subtitle": "subtitlealbum3",
          "jpeg": "../img/album3.jpg",
          "price": "13.00",
          "anystring1": "anystring1album3",
          "anystring2": "anystring2album3"
        }
      ]
    },
    {
      "name": "artist2name",
      "jpeg": "../img/artist/artist2.jpg",
      "albums": []
    }
  ]
}

Un tableau peut être vide comme dans mon exemple (aucun album n'a été attribué à l'artiste2).

Vous avez également une mauvaise affectation dans votre ListCtrl, vous ne pouvez pas affecter et afficher des albums tant que vous ne connaissez pas la bonne Artist. Si vous souhaitez afficher tous les albums de tous les artistes, vous devez parcourir tous les artistes.

Exemple de contrôleur:


angular.module('list', []);

function ListCtrl($scope, $http) {
  $http({
    method: 'GET',
    url: 'json_price_1.json'
  }).success(function(data) {
    $scope.artists = data.artists; // response data
    $scope.albums = [];
    angular.forEach(data.artists, function(artist, index) {
      angular.forEach(artist.albums, function(album, index){
        $scope.albums.Push(album);
      });
    });
  });
}

Voici Plunkr modifié basé sur l'exemple de Jessie: http://plnkr.co/edit/zkUqrPjlDYhVeNEZY1YR?p=preview

6
ivoszz

Vérifier lien Plunker

Répondez à votre question "comment vais-je sélectionner sur ce JSON imbriqué?" 

$.each(data.artists, function(index, element){
  $.each(this.albums, function(index, element){
    $scope.albums.Push(element);
  });
});

Répondez à votre question "comment vais-je filtrer ces artistes avec un champ de texte?"

<input ng-model="searchText.artistName">

<ul ng-repeat="album in albums | filter:searchText">
    <li>{{album.title}}</li>
</ul>
4
jessie
<ul ng-repeat="artist in artists">
    <li>
        <p>{{artist.name}}</p> 

        <ul ng-repeat="(key,val) in artist.albums">

            <li>{{key}} - {{val}}</li>

        </ul> 
    </li>
</ul>
0
Noredine Bahri