Passer des arguments aux filtres angularjs

99

Est-il possible de passer un argument à la fonction de filtrage afin de pouvoir filtrer par n'importe quel nom?

Quelque chose comme

$scope.weDontLike = function(item, name) {
    console.log(arguments);
    return item.name != name;
};
métamorphe
la source

Réponses:

223

En fait, il existe une autre solution (peut-être meilleure) où vous pouvez utiliser le filtre natif de `` filtre '' angulaire et toujours transmettre des arguments à votre filtre personnalisé.

Considérez le code suivant:

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

Pour que cela fonctionne, définissez simplement votre filtre comme suit:

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

Comme vous pouvez le voir ici, weDontLike renvoie en fait une autre fonction qui a votre paramètre dans sa portée ainsi que l'élément d'origine provenant du filtre.

Il m'a fallu 2 jours pour réaliser que vous pouvez le faire, je n'ai encore vu cette solution nulle part.

Checkout Inverser la polarité d'un filtre angular.js pour voir comment vous pouvez l'utiliser pour d'autres opérations utiles avec le filtre.

Denis Pshenov
la source
Si
nh2
Cette méthode a également résolu un problème étrange où à l'intérieur de ng-repeat, je ne pouvais pas passer mes propres paramètres à mon filtre. Peu importe ce que j'ai fait, ils revenaient sans cesse en tant qu'index et collection globale. En faisant cette méthode de retour, j'ai pu passer mes paramètres et toujours charger l'élément d'origine, bonne correction!
Dennis Smolek
Cette réponse a résolu mon problème où je ne pouvais pas passer une variable $ scope en tant que paramètre à la fonction de filtre. Meilleure solution. Vote positif!
valafar
Si je pouvais voter pour cela plus d'une fois, je m'assurerais que c'était la réponse la plus votée de l'histoire de SO. Cela me dérange depuis des années ... et puis je trouve la réponse (maintenant âgée de 2 ans) ... Merci infiniment beaucoup.
PKD
Toujours utile en 2019! Merci beaucoup.
ashilon
76

D'après ce que je comprends, vous ne pouvez pas passer d'arguments à une fonction de filtre (lorsque vous utilisez le filtre «filtre»). Ce que vous auriez à faire est d'écrire un filtre personnalisé, qc comme ceci:

.filter('weDontLike', function(){

return function(items, name){

    var arrayToReturn = [];        
    for (var i=0; i<items.length; i++){
        if (items[i].name != name) {
            arrayToReturn.push(items[i]);
        }
    }

    return arrayToReturn;
};

Voici le jsFiddle fonctionnel: http://jsfiddle.net/pkozlowski_opensource/myr4a/1/

L'autre alternative simple, sans écrire de filtres personnalisés, consiste à stocker un nom à filtrer dans une portée, puis à écrire:

$scope.weDontLike = function(item) {
  return item.name != $scope.name;
};
pkozlowski.opensource
la source
C'est parfait merci! Stocker le nom dans la portée ne fonctionnera pas aussi bien que j'ai trois listes des mêmes données sur la même page en filtrant avec différents états (ou noms).
shapeshifter
any pour définir 'Adam' (en référence à votre JSFiddle) dynamiquement? il semble impossible (et je suppose que c'est exprès) de combiner ngModel et un filtre personnalisé dans Angular ...
Rolf
Est-il possible de réorganiser les paramètres d'un filtre? Par exemple, passez l'élément au deuxième paramètre d'un filtre?
Pooya
Il convient de noter que dans cet exemple, le balisage est {{items | weDontLike: 'thenameyoudontlike'}} ... pour l'instant, vous devez aller au violon pour l'obtenir. Il convient également de noter que vous pouvez transmettre plusieurs paramètres à votre filtre personnalisé {{items | weDontLike: 'thename': ['Je suis', 'un tableau']: 'et ainsi de suite'}} il vous suffit d'ajouter plus d'arguments à votre filtre personnalisé pour y avoir accès.
Benjamin Conant
62

En fait, vous pouvez passer un paramètre ( http://docs.angularjs.org/api/ng.filter:filter ) et vous n'avez pas besoin d'une fonction personnalisée juste pour cela. Si vous réécrivez votre HTML comme ci-dessous, cela fonctionnera:

<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>
</div>

http://jsfiddle.net/ZfGx4/59/

mikel
la source
8
Oui. Note latérale - si le nom de quelqu'un est "! Adam", vous l'obtenez comme {nom: "!! Adam"}.
honzajde
5
Vous pouvez également passer des tableaux ici aussi comme celui-cifilter:['Adam', 'john']
iConnor
6
Le lien jsfiddle est rompu.
Seregwethrin
4
! Adam est le pire nom de tous les temps
Ben Wheeler
6
Not-Not-Adam est évidemment pire.
twip
30

Vous pouvez simplement faire comme ceci dans le modèle

<span ng-cloak>{{amount |firstFiler:'firstArgument':'secondArgument' }}</span>

Dans le filtre

angular.module("app")
.filter("firstFiler",function(){

    console.log("filter loads");
    return function(items, firstArgument,secondArgument){
        console.log("item is ",items); // it is value upon which you have to filter
        console.log("firstArgument is ",firstArgument);
        console.log("secondArgument ",secondArgument);

        return "hello";
    }
    });
abhaygarg12493
la source
C'est la meilleure réponse. Il fonctionne avec des objets dynamiques. Cela devrait être la réponse acceptée.
abelabbesnabi
2

En étendant la réponse de pkozlowski.opensource et en utilisant la array'sméthode de filtre intégré javascript , une solution précieuse pourrait être la suivante:

.filter('weDontLike', function(){
    return function(items, name){
        return items.filter(function(item) {
            return item.name != name;
        });
    };
});

Voici le lien jsfiddle .

Plus d'informations sur le filtre Array ici .

Nasif Md. Tanjim
la source
1

Vous pouvez passer plusieurs arguments au filtre angulaire!

Définition de mon application angulaire et d'une variable au niveau de l'application -

var app = angular.module('filterApp',[]);
app.value('test_obj', {'TEST' : 'test be check se'});

Votre filtre sera comme: -

app.filter('testFilter', [ 'test_obj', function(test_obj) {
    function test_filter_function(key, dynamic_data) {
      if(dynamic_data){
        var temp = test_obj[key]; 
        for(var property in dynamic_data){
            temp = temp.replace(property, dynamic_data[property]);
        }
        return temp;
      }
      else{
        return test_obj[key] || key;
      }

    }
    test_filter_function.$stateful = true;
    return test_filter_function;
  }]);

Et à partir du HTML, vous enverrez des données telles que: -

<span ng-bind="'TEST' | testFilter: { 'be': val, 'se': value2 }"></span>

Ici, j'envoie un objet JSON au filtre. Vous pouvez également envoyer tout type de données comme une chaîne ou un nombre.

vous pouvez également passer un nombre dynamique d'arguments à filtrer, dans ce cas, vous devez utiliser des arguments pour obtenir ces arguments.

Pour une démonstration fonctionnelle, allez ici - en passant plusieurs arguments au filtre angulaire

Partha Roy
la source
0

Vous pouvez simplement utiliser | filter:yourFunction:arg

<div ng-repeat="group in groups | filter:weDontLike:group">...</div>

Et en js

$scope.weDontLike = function(group) {
//here your condition/criteria
return !!group 
}
user2972221
la source