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') }">
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.
Pour moi, cela a fonctionné comme indiqué ci-dessous ..
<div ng-repeat="product in products | filter: { color: 'red'} | filter: { color:'blue' }">
Je pense que "ng-if" devrait fonctionner:
<div ng-repeat="product in products" ng-if="product.color === 'red'
|| product.color === 'blue'">
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;
}
};
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>
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.
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.
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>