web-dev-qa-db-fra.com

Angular js foreach ne retournant que le dernier élément du tableau

J'essaie de renvoyer chaque objet d'élément depuis un JSON et d'évaluer sa valeur, avec la fonction angular.forEach(), mais seul le dernier élément est renvoyé. Et à cause de cela, je ne peux effectuer aucune évaluation. Assez drôle, si je fais console.log(), il affiche chaque élément, un par un. 

Comment puis-je obtenir chaque article et les évaluer?

Si vous connaissez un meilleur moyen, enseignez-moi s'il vous plaît.

JS (angularjs):

angular.module('bLiApp')
  .controller('AddDataCtrl', ['$scope', 'DataService', function ($scope, DataService) {

    DataService.getItems().success(function(data) {

      $scope.items = data.category.items;

      angular.forEach($scope.items, function(item) {

        // This is where I'm having problem with return data...
        if (item.amount < 600) {
          $scope.amountchecker = 'low';
        } else if (item.amount >= 600 && item.amount <= 650) {
          $scope.amountchecker = 'average';
        } else if (item.amount > 650) {
          $scope.amountchecker = 'too high';
        }

      });
    });
  }]);

HTML (angularjs):

<div class="add-data" ng-controller="AddDataCtrl">
  <div class="data-box clearfix" ng-repeat="item in items">
    <article class="item">
      <p>{{amountchecker}}</p>
      <p><span class="month">{{ item.month.substring(0, 3) }}</span></p>
      <p class="cost">{{item.cost | currency:"&pound;"}}</p>
    </article>
  </div>
</div>

Merci beaucoup

7
Shaoz

En fait, vous n'avez pas besoin d'une boucle forEach pour y parvenir:

<div class="add-data" ng-controller="AddDataCtrl">

 <div class="data-box clearfix" ng-repeat="item in items">
    <article class="item">
      <p>
         <span ng-if="item.amount < 600">Low</span>
         <span ng-if="item.amount >= 600 && <= 650">Average</span>
         <span ng-if="item.amount < 650">Too high</span>
      </p>
      <p><span class="month">{{ item.month.substring(0, 3) }}</span></p>
      <p class="cost">{{item.cost | currency:"&pound;"}}</p>
    </article>
  </div>
</div>

Cela devrait faire le travail. Notez que cela affichera seulement le montant, si vous souhaitez le modifier dans le modèle (si vous devez renvoyer les données que vous venez d'évaluer), vous devez modifier les données dans le contrôleur:

  angular.forEach($scope.items, function(item) {
    item.amountChecker; // declare a new property for each item in $scope.items
    // then we set the value for each item
    if (item.amount < 600) {
      item.amountChecker = 'low';
    } else if (item.amount >= 600 && item.amount <= 650) {
      item.amountChecker = 'average';
    } else if (item.amount > 650) {
      item.amountChecker = 'too high';
    }

  });

Cela devrait ajouter une nouvelle ligne à votre objet $ scope.items, où montantChecker sera attribué à chaque élément. Ensuite, dans votre ng-repeat, vous pouvez également afficher cette valeur: item.amountChecker

Cette fois, il appellera la propriété amountChecker de chaque élément à la place de la dernière valeur stockée dans $ scope.amountchecker.

Notez que Goodzilla a effectivement répondu dans un commentaire, de manière plus courte :)

5
enguerranws

Vous semblez écraser $scope.amountchecker à chaque itération de la boucle via $scope.items. Si $scope.items avait un élément avec amount de 500 suivi d'un élément avec amount de 650, $scope.amountchecker finirait par être réglé sur 'moyenne', 650 étant le montant du dernier élément rencontré dans la boucle. 

La solution dépend si vous voulez réellement que amountchecker soit basé sur tous les éléments ou sur un seul élément. Dans ce dernier cas, vous modifieriez vos lignes telles que:

$scope.amountchecker = 'low';

À

item.amountchecker = 'low';
1
Chris Peacock