web-dev-qa-db-fra.com

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 Part:

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

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

Mais de toute façon, il me montre tous les articles. Comment puis-je filtrer sur (clé, valeur)?

108
Vural Acar

Angular filters ne peut être appliqué qu'à des tableaux et non à des objets, à partir de l'API angular -

"Sélectionne un sous-ensemble d’éléments du tableau et le renvoie sous la forme d’un 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/

126
bmleite

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
Valentyn Shybanov

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

<div ng-repeat="(key, value) in order" ng-if="value > 0">
25
DenisKolodin

Ou simplement utiliser

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

Voir la solution mise à jour ici:

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

21
Renaud

Vous pouvez simplement utiliser angular.filter module, puis filtrer même par 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
a8m

Il est un peu tard, mais j’ai cherché un filtre similaire et 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>
7
ph6

Bien que cette question soit plutôt ancienne, j'aimerais partager ma solution pour les développeurs angulaires 1. Le but est simplement de réutiliser le filtre angulaire d'origine, mais en passant de manière transparente tous les objets sous forme de 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
ollix

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

  • objet = l'objet à filtrer
  • champ = le champ dans cet objet sur lequel nous allons filtrer
  • filter = 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
BelgoCanadian