web-dev-qa-db-fra.com

Angular.js ng-repeat filter par propriété ayant une ou plusieurs valeurs (OU de valeurs)

Est-il possible de filtrer un tableau d'objets, de telle sorte que la valeur de la propriété puisse être composée de quelques valeurs (condition OR) sans écrire de filtre personnalisé

Ceci est similaire à ce problème - Angular.js ng-repeat: filtrer par champ unique

Mais au lieu de 

<div ng-repeat="product in products | filter: { color: 'red' }">

est-il possible de faire quelque chose comme ça

<div ng-repeat="product in products | filter: { color: 'red'||'blue' }">

pour un échantillon de données comme suit-

$scope.products = [
   { id: 1, name: 'test', color: 'red' },
   { id: 2, name: 'bob', color: 'blue' }
   /*... etc... */
];

J'ai essayé sans succès 

<div ng-repeat="product in products | filter: { color: ('red'||'blue') }">
50
Yogesh Mangaj

La meilleure façon de faire est d’utiliser une fonction:

<div ng-repeat="product in products | filter: myFilter">

$scope.myFilter = function (item) { 
    return item === 'red' || item === 'blue'; 
};

Vous pouvez également utiliser ngHide ou ngShow pour afficher et masquer de manière dynamique des éléments en fonction de certains critères. 

85
Sherlock

Pour moi, cela a fonctionné comme indiqué ci-dessous ..

<div ng-repeat="product in products | filter: { color: 'red'} | filter: { color:'blue' }">

25
Amol Aranke

Je pense que "ng-if" devrait fonctionner:

<div ng-repeat="product in products" ng-if="product.color === 'red' 
|| product.color === 'blue'">
14
jbrook10

En HTML:

<div ng-repeat="product in products | filter: colorFilter">

En angulaire:

$scope.colorFilter = function (item) { 
  if (item.color === 'red' || item.color === 'blue') {
  return item;
 }
};
9
bboyonly

Voici un moyen de le faire en passant un argument supplémentaire:

https://stackoverflow.com/a/17813797/4533488 (merci à Denis Pshenov)

<div ng-repeat="group in groups">
    <li ng-repeat="friend in friends | filter:weDontLike(group.enemy.name)">
        <span>{{friend.name}}</span>
    <li>
</div>

Avec le backend: 

$scope.weDontLike = function(name) {
    return function(friend) {
        return friend.name != name;
    }
}

.


Et encore une autre façon avec un filtre dans le modèle uniquement:

https://stackoverflow.com/a/12528093/4533488 (merci à mikel)

<div ng:app>
  <div ng-controller="HelloCntl">
    <ul>
       <li ng-repeat="friend in friends | filter:{name:'!Adam'}">
            <span>{{friend.name}}</span>
            <span>{{friend.phone}}</span>
        </li>
    </ul>
</div>

6
aero

J'ai trouvé une solution plus générique avec la solution native la plus angulaire que je puisse penser. En gros, vous pouvez transmettre votre propre comparateur à la fonction filterFilter par défaut. Voici plunker également.

3
s.alem

Après avoir été incapable de trouver une bonne solution universelle, j'ai fait quelque chose de mon cru. Je ne l'ai pas testé pour une très grande liste.

Il prend en charge les clés imbriquées, les tableaux ou à peu près n'importe quoi.

Voici le github et demo

app.filter('xf', function() {
    function keyfind(f, obj) {
        if (obj === undefined)
            return -1;
        else {
            var sf = f.split(".");
            if (sf.length <= 1) {
                return obj[sf[0]];
            } else {
                var newobj = obj[sf[0]];
                sf.splice(0, 1);
                return keyfind(sf.join("."), newobj)
            }
        }

    }
    return function(input, clause, fields) {
        var out = [];
        if (clause && clause.query && clause.query.length > 0) {
            clause.query = String(clause.query).toLowerCase();
            angular.forEach(input, function(cp) {
                for (var i = 0; i < fields.length; i++) {
                    var haystack = String(keyfind(fields[i], cp)).toLowerCase();
                    if (haystack.indexOf(clause.query) > -1) {
                        out.Push(cp);
                        break;
                    }
                }
            })
        } else {
            angular.forEach(input, function(cp) {
                out.Push(cp);
            })
        }
        return out;
    }

})

HTML 

<input ng-model="search.query" type="text" placeholder="search by any property">
<div ng-repeat="product in products |  xf:search:['color','name']">
...
</div>
0
Raj Sharma