Comment filtrer (clé, valeur) avec ng-repeat dans AngularJs?

J'essaie de faire quelque chose comme:

<div ng-controller="TestCtrl">
    <div ng-repeat="(k,v) in items | filter:hasSecurityId">
        {{k}} {{v.pos}}
    </div>
</div>

AngularJs Partie:

function TestCtrl($scope) 
{
    $scope.items = {
                     'A2F0C7':{'secId':'12345', 'pos':'a20'},
                     'C8B3D1':{'pos':'b10'}
                   };

    $scope.hasSecurityId = function(k,v)
    {
       return v.hasOwnProperty('secId');
    }
}

Mais en quelque sorte, il me montre tous les éléments. Comment puis-je filtrer (clé,valeur) ?

105
demandé sur Damjan Pavlica 2013-02-09 17:25:52

8 réponses

Angular les filtres ne peuvent être appliqués qu'aux tableaux et non aux objets, à partir de l'API d'angular -

" sélectionne un sous-ensemble d'éléments du tableau et le renvoie en tant que nouveau tableau."

, Vous avez deux options ici:
1) déplacez $scope.items vers un tableau ou -
2) pré-filtrer les éléments ng-repeat, comme ceci:

<div ng-repeat="(k,v) in filterSecId(items)">
    {{k}} {{v.pos}}
</div>

Et sur le Contrôleur:

$scope.filterSecId = function(items) {
    var result = {};
    angular.forEach(items, function(value, key) {
        if (!value.hasOwnProperty('secId')) {
            result[key] = value;
        }
    });
    return result;
}

Jsfiddle: http://jsfiddle.net/bmleite/WA2BE/

124
répondu bmleite 2016-01-14 21:14:16

Ma solution serait de créer un filtre personnalisé et de l'utiliser:

app.filter('with', function() {
  return function(items, field) {
        var result = {};
        angular.forEach(items, function(value, key) {
            if (!value.hasOwnProperty(field)) {
                result[key] = value;
            }
        });
        return result;
    };
});

Et en html:

 <div ng-repeat="(k,v) in items | with:'secId'">
        {{k}} {{v.pos}}
 </div>
45
répondu Valentyn Shybanov 2013-02-09 16:13:07

Ou utilisez simplement

ng-show="v.hasOwnProperty('secId')"

Voir la solution mise à jour ici:

Http://jsfiddle.net/RFontana/WA2BE/93/

21
répondu Renaud 2013-10-22 14:07:49

Aussi, vous pouvez utiliser ng-repeat avec ng-if:

<div ng-repeat="(key, value) in order" ng-if="value > 0">
21
répondu DenisKolodin 2015-12-09 22:16:24

Vous pouvez simplement utiliser angulaire.filtre module, puis vous pouvez filtrer même par des propriétés imbriquées.
voir: jsbin
2 Exemples:

JS:

angular.module('app', ['angular.filter'])
  .controller('MainCtrl', function($scope) {
  //your example data
  $scope.items = { 
    'A2F0C7':{ secId:'12345', pos:'a20' },
    'C8B3D1':{ pos:'b10' }
  };
  //more advantage example
  $scope.nestedItems = { 
    'A2F0C7':{
      details: { secId:'12345', pos:'a20' }
    },
    'C8B3D1':{
      details: { pos:'a20' }
    },
    'F5B3R1': { secId:'12345', pos:'a20' }
  };
});

HTML:

  <b>Example1:</b>
  <p ng-repeat="item in items | toArray: true | pick: 'secId'">
    {{ item.$key }}, {{ item }}
  </p>

  <b>Example2:</b>
  <p ng-repeat="item in nestedItems | toArray: true | pick: 'secId || details.secId' ">
    {{ item.$key }}, {{ item }}
  </p> 
11
répondu a8m 2015-02-13 10:37:46

C'est un peu tard, mais j'ai cherché un filtre similaire et j'ai fini par utiliser quelque chose comme ceci:

<div ng-controller="TestCtrl">
 <div ng-repeat="(k,v) in items | filter:{secId: '!!'}">
   {{k}} {{v.pos}}
 </div>
</div>
6
répondu ph6 2016-02-05 08:25:52

J'ai fait un peu plus d'un filtre générique que j'ai utilisé dans plusieurs projets déjà:

  • object = objet qui doit être filtré
  • field = le champ dans cet objet sur lequel nous allons filtrer
  • filtre = la valeur du filtre qui doit correspondre au champ

HTML:

<input ng-model="customerNameFilter" />
<div ng-repeat="(key, value) in filter(customers, 'customerName', customerNameFilter" >
   <p>Number: {{value.customerNo}}</p>
   <p>Name: {{value.customerName}}</p>
</div>

JS:

  $scope.filter = function(object, field, filter) {
    if (!object) return {};
    if (!filter) return object;

    var filteredObject = {};
    Object.keys(object).forEach(function(key) {
      if (object[key][field] === filter) {
        filteredObject[key] = object[key];
      }
    });

    return filteredObject;
  };
0
répondu BelgoCanadian 2017-06-15 22:23:41

Bien que cette question soit plutôt ancienne, j'aimerais partager ma solution pour les développeurs angular 1. Le but est de simplement réutiliser le filtre angulaire d'origine, mais en passant de manière transparente tous les objets en tant que tableau.

app.filter('objectFilter', function ($filter) {
    return function (items, searchToken) {
        // use the original input
        var subject = items;

        if (typeof(items) == 'object' && !Array.isArray(items)) {
            // or use a wrapper array, if we have an object
            subject = [];

            for (var i in items) {
                subject.push(items[i]);
            }
        }

        // finally, apply the original angular filter
        return $filter('filter')(subject, searchToken);
    }
});

Utilisez-le comme ceci:

<div>
    <input ng-model="search" />
</div>
<div ng-repeat="item in test | objectFilter : search">
    {{item | json}}
</div>

Voici un plunker

0
répondu ollix 2017-11-09 11:51:50