ng-repeat: filtrer par champ unique

484

J'ai une gamme de produits que je répète en utilisant ng-repeat et j'utilise

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

pour filtrer ces produits par couleur. Le filtre fonctionne mais si le nom / description du produit, etc. contient la couleur, le produit reste après l'application du filtre.

Comment définir le filtre pour qu'il s'applique uniquement au champ de couleur de ma matrice plutôt qu'à chaque champ?

Tim Webster
la source
Les filtres personnalisés sont également puissants =), cela pourrait vous plaire, exemple: noypi-linux.blogspot.com/2014/07/…
Noypi Gilas
Solution différente: stackoverflow.com/a/24992197/257470
andrew.fox
Un excellent travail qui
épelle

Réponses:

475

Voir l'exemple sur la page de filtre . Utilisez un objet et définissez la couleur dans la propriété color:

Search by color: <input type="text" ng-model="search.color">
<div ng-repeat="product in products | filter:search"> 
Mark Rajcok
la source
Merci Mark, y a-t-il des avantages à le faire de cette façon plutôt que la méthode suggérée ci-dessous?
Tim Webster
7
@Seglespaan, pas vraiment. Vous trouverez peut-être que la méthode présentée par bmleite et blesh est plus agréable, car vous pouvez voir que vous filtrez par couleur. Cette méthode est plus compacte, ce qui pourrait être utile si vous souhaitez rechercher par plusieurs propriétés, et que vous préférez ne pas avoir un objet long dans le code HTML: filter:{ color: '...', size: '...', ...}
Mark Rajcok
2
@MarkRajcok, comment pourrais-je rechercher par plusieurs propriétés, en regardant l'union, plutôt que l'intersection?
jetcom
2
@jetcom, vous aurez besoin d'un filtre personnalisé, voir stackoverflow.com/a/13845135/215945
Mark Rajcok
1
Je ne sais pas si l'OP demandait comment créer une boîte de recherche autant que comment filtrer les valeurs dans une répétition ng lorsqu'elles se répètent à la page. La réponse sous celle-ci semble la plus pertinente pour la question posée.
twknab
573

Spécifiez la propriété (c'est-à-dire colour) à laquelle vous souhaitez appliquer le filtre:

<div ng-repeat="product in products | filter:{ colour: by_colour }">
bmleite
la source
5
Et si je veux! by_colour comme filtre: {color:! by_colour} "
rjdmello
27
@rjdmello vient d'ajouter '!'+, comme ceci<div ng-repeat="product in products | filter:{ colour: '!'+by_colour }">
bmleite
3
Je ne sais pas si je l'ai bien compris, mais la première chose qui vient à mon esprit était: <div ng-repeat="product in products | filter:{ resultsMap.annie: '!!' }"> ou (quelque chose d' équivalent) comme celui - ci: <div ng-repeat="product in products | filter:by">et sur le contrôleur: $scope.by = { 'resultsMap.annie': '!!' };. Cette deuxième approche vous donne plus de contrôle sur la propriété filtrée. Remarque: '!!'signifie "non nul".
bmleite
2
@Federico, le customFilterpeut être un simple objet sur votre ordinateur scopeque vous mettez à jour à tout moment. Vérifiez ce plunker .
bmleite
1
Ce devrait être la réponse acceptée. C'est le plus succinct. Eh bien, sauf que la «couleur» a trop de voyelles.
Rap
176

Vous pouvez filtrer par un objet avec une propriété correspondant aux objets que vous devez filtrer dessus:

app.controller('FooCtrl', function($scope) {
   $scope.products = [
       { id: 1, name: 'test', color: 'red' },
       { id: 2, name: 'bob', color: 'blue' }
       /*... etc... */
   ];
});
<div ng-repeat="product in products | filter: { color: 'red' }"> 

Cela peut bien sûr être transmis par variable, comme l'a suggéré Mark Rajcok.

Ben Lesh
la source
2
disons que j'ai ce genre de scope.products: {id: 1, nom: 'test', couleur: 'lightblue'}, {id: 2, nom: 'bob', couleur: [{premier plan: noir, fond :blanc}] }. alors comment puis-je filtrer le produit en fonction de la couleur: arrière-plan pour obtenir une valeur blanche?
Gery
2
@Gery: Honnêtement, je ne pense pas que vous puissiez. Quoi qu'il en soit, utiliser le filtre: c'est en quelque sorte une mauvaise pratique, OMI. En cela, il met la logique à votre avis qui devrait vraiment être dans votre contrôleur, et n'est pas très testable.
Ben Lesh
C'est un moyen de déplacer le filtrage vers le contrôleur et d'étendre le modèle. ozkary.com/2015/05/angularjs-value-mapping-with-dynamic.html .
ozkary
106

Si vous souhaitez filtrer sur un petit-enfant (ou plus profond) de l'objet donné, vous pouvez continuer à développer votre hiérarchie d'objet. Par exemple, si vous souhaitez filtrer sur 'thing.properties.title', vous pouvez effectuer les opérations suivantes:

<div ng-repeat="thing in things | filter: { properties: { title: title_filter } }">

Vous pouvez également filtrer sur plusieurs propriétés d'un objet simplement en les ajoutant à votre objet filtre:

<div ng-repeat="thing in things | filter: { properties: { title: title_filter, id: id_filter } }">
David Hansen
la source
2
est-ce comme "ou" type ou "et" type de filtre.
sms
1
La même question est qu'un AND ou un OR lors du filtrage de plusieurs propriétés?
lostintranslation
1
pour le filtre OU seul moyen est un filtre personnalisé, je pense
Dmitri Algazin
99

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

html

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

javascript

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

Alternativement, vous pouvez utiliser ngHide ou ngShow pour afficher et masquer dynamiquement des éléments en fonction de certains critères.

Khader MA
la source
64

Soyez prudent avec le filtre angulaire. Si vous souhaitez sélectionner une valeur spécifique dans le champ, vous ne pouvez pas utiliser de filtre.

Exemple:

javascript

app.controller('FooCtrl', function($scope) {
   $scope.products = [
       { id: 1, name: 'test', color: 'lightblue' },
       { id: 2, name: 'bob', color: 'blue' }
       /*... etc... */
   ];
});

html

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

Cela sélectionnera les deux, car utiliser quelque chose comme substr
Cela signifie que vous voulez sélectionner le produit où "couleur" contient la chaîne "bleu" et non où "couleur" est "bleu".

Petr B.
la source
88
<div ng-repeat="product in products | filter: { color: 'blue' }:true">ne fonctionnera que sur les correspondances exactes (le «vrai» à la fin est l'argument de comparaison: lien
Mark
21

Recherche par couleur:

<input type="text" ng-model="searchinput">
<div ng-repeat="product in products | filter:{color:searchinput}">

vous pouvez aussi faire un nid intérieur.

filter:{prop1:{innerprop1:searchinput}}
CyberNinja
la source
10

Si vous deviez faire ce qui suit:

<li class="active-item" ng-repeat="item in mc.pageData.items | filter: { itemTypeId: 2, itemStatus: 1 } | orderBy : 'listIndex'"
                id="{{item.id}}">
    <span class="item-title">{{preference.itemTitle}}</span>
</li>

... vous obtiendrez non seulement des éléments de itemTypeId 2 et itemStatus 1, mais vous obtiendrez également des éléments avec itemType 20, 22, 202, 123 et itemStatus 10, 11, 101, 123. Cela est dû au fait que le filtre: {.. .} la syntaxe fonctionne comme une chaîne contient une requête.

Cependant, si vous ajoutiez la condition : true , elle filtrerait par correspondance exacte:

<li class="active-item" ng-repeat="item in mc.pageData.items | filter: { itemTypeId: 2, itemStatus: 1 } : true | orderBy : 'listIndex'"
                id="{{item.id}}">
    <span class="item-title">{{preference.itemTitle}}</span>
</li>
Phil
la source
4

ma façon est la suivante

subjcts is

[{"id":"1","title":"GFATM"},{"id":"2","title":"Court Case"},{"id":"3","title":"Renewal\/Validity"},{"id":"4","title":"Change of Details"},{"id":"5","title":"Student Query"},{"id":"6","title":"Complains"}]

sous est un champ d'entrée ou tout ce que vous aimez

Affichage comme ceci

<div ng-if="x.id === sub" ng-repeat=" x in subjcts">{{x.title}}</div>
Asad Ali Khan
la source
En général, utiliser ng-if est une solution propre
Kilizo
4

Vous devez utiliser filter:{color_name:by_colour}au lieu de

filter:by_colour

Si vous souhaitez faire correspondre avec une seule propriété d'un objet, écrivez cette propriété au lieu de l'objet, sinon une autre propriété obtiendra une correspondance.

amit banerjee
la source
1

Spécifiez la propriété dans le filtre, de l'objet sur lequel vous souhaitez appliquer le filtre:

//Suppose Object
var users = [{
  "firstname": "XYZ",
  "lastname": "ABC",
  "Address": "HOUSE NO-1, Example Street, Example Town"
},
{
  "firstname": "QWE",
  "lastname": "YUIKJH",
  "Address": "HOUSE NO-11, Example Street1, Example Town1"
}]

Mais vous souhaitez appliquer le filtre uniquement sur le prénom

<input type = "text" ng-model = "first_name_model"/>
<div ng-repeat="user in users| filter:{ firstname: first_name_model}">
Neeraj Bansal
la source
0

Si vous souhaitez filtrer pour un champ:

label>Any: <input ng-model="search.color"></label> <br>
<tr ng-repeat="friendObj in friends | filter:search:strict">

Si vous souhaitez filtrer tous les champs:

 label>Any: <input ng-model="search.$"></label> <br>
 <tr ng-repeat="friendObj in friends | filter:search:strict">

et https://docs.angularjs.org/api/ng/filter/filter bon pour vous

milad dn
la source