131 votes

Comment faire en sorte que ng-repeat filtre les résultats en doublon

Je fais tourner un simple ng-repeat sur un fichier JSON et je veux obtenir les noms des catégories. Il y a environ 100 objets, chacun appartenant à une catégorie - mais il n'y a qu'environ 6 catégories.

Mon code actuel est le suivant :

  {{place.category}}

La sortie est de 100 options différentes, principalement des doublons. Comment puis-je utiliser Angular pour vérifier si {{place.category}} existe déjà et ne pas créer une option s'il est déjà là ?

edit: Dans mon JavaScript, $scope.places = données JSON, juste pour clarifier

2voto

shoesel Points 31

Voici une manière de le faire avec uniquement un modèle de template (mais cela ne maintient pas l'ordre). De plus, le résultat sera également trié, ce qui est utile dans la plupart des cas :

      {{place.category}}

2voto

Black Mamba Points 2255

Aucun des filtres ci-dessus n'a résolu mon problème, j'ai donc dû copier le filtre à partir de la documentation officielle de github doc. Et ensuite l'utiliser comme expliqué dans les réponses ci-dessus

angular.module('votreNomApplicationIci').filter('unique', function () {

return function (items, filterOn) {

if (filterOn === false) {
  return items;
}

if ((filterOn || angular.isUndefined(filterOn)) && angular.isArray(items)) {
  var hashCheck = {}, newItems = [];

  var extractValueToCompare = function (item) {
    if (angular.isObject(item) && angular.isString(filterOn)) {
      return item[filterOn];
    } else {
      return item;
    }
  };

  angular.forEach(items, function (item) {
    var valueToCheck, isDuplicate = false;

    for (var i = 0; i < newItems.length; i++) {
      if (angular.equals(extractValueToCompare(newItems[i]), extractValueToCompare(item))) {
        isDuplicate = true;
        break;
      }
    }
    if (!isDuplicate) {
      newItems.push(item);
    }

  });
  items = newItems;
}
return items;
  };

});

1voto

thethakuri Points 103

Si vous voulez obtenir des données uniques basées sur la clé imbriquée :

app.filter('unique', function() {
        return function(collection, primaryKey, secondaryKey) { //clé secondaire facultative
          var output = [], 
              keys = [];

          angular.forEach(collection, function(item) {
                var key;
                secondaryKey === undefined ? key = item[primaryKey] : key = item[primaryKey][secondaryKey];

                if(keys.indexOf(key) === -1) {
                  keys.push(key);
                  output.push(item);
                }
          });

          return output;
        };
    });

Appelez-le comme ceci :

0voto

Shawn Dotey Points 516

Ajouter ce filtre :

app.filter('unique', function () {
return function ( collection, keyname) {
var output = [],
    keys = []
    found = [];

if (!keyname) {

    angular.forEach(collection, function (row) {
        var is_found = false;
        angular.forEach(found, function (foundRow) {

            if (foundRow == row) {
                is_found = true;                            
            }
        });

        if (is_found) { return; }
        found.push(row);
        output.push(row);

    });
}
else {

    angular.forEach(collection, function (row) {
        var item = row[keyname];
        if (item === null || item === undefined) return;
        if (keys.indexOf(item) === -1) {
            keys.push(item);
            output.push(row);
        }
    });
}

return output;
};
});

Mettre à jour votre balisage:

   {{place.category}}

0voto

Ikechi Michael Points 389

Cela peut sembler excessif, mais cela fonctionne pour moi.

Array.prototype.contains = function (item, prop) {
var arr = this.valueOf();
if (prop == undefined || prop == null) {
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] == item) {
            return true;
        }
    }
}
else {
    for (var i = 0; i < arr.length; i++) {
        if (arr[i][prop] == item) return true;
    }
}
return false;
}

Array.prototype.distinct = function (prop) {
   var arr = this.valueOf();
   var ret = [];
   for (var i = 0; i < arr.length; i++) {
       if (!ret.contains(arr[i][prop], prop)) {
           ret.push(arr[i]);
       }
   }
   arr = [];
   arr = ret;
   return arr;
}

La fonction distinct dépend de la fonction contains définie ci-dessus. Elle peut être appelée comme array.distinct(prop); où prop est la propriété que vous voulez rendre distincte.

Donc, vous pourriez simplement dire $scope.places.distinct("category");

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X