Übergeben von Argumenten an AngularJS-Filter

99

Ist es möglich, ein Argument an die Filterfunktion zu übergeben, damit Sie nach einem beliebigen Namen filtern können?

Etwas wie

$scope.weDontLike = function(item, name) {
    console.log(arguments);
    return item.name != name;
};
Gestaltwandler
quelle

Antworten:

223

Tatsächlich gibt es eine andere (möglicherweise bessere) Lösung, bei der Sie den nativen Filterfilter des Winkels verwenden und trotzdem Argumente an Ihren benutzerdefinierten Filter übergeben können.

Betrachten Sie den folgenden Code:

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

Damit dies funktioniert, definieren Sie Ihren Filter einfach wie folgt:

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

Wie Sie hier sehen können, gibt weDontLike tatsächlich eine andere Funktion zurück, deren Gültigkeitsbereich Ihren Parameter sowie das ursprüngliche Element aus dem Filter enthält.

Ich habe 2 Tage gebraucht, um zu erkennen, dass Sie dies tun können. Ich habe diese Lösung noch nirgendwo gesehen.

Checkout Verpolung eines Angular.js-Filters umkehren, um zu sehen, wie Sie dies für andere nützliche Operationen mit Filter verwenden können.

Denis Pshenov
quelle
Falls Ihr Filter mehrere Argumente benötigt, lesen
nh2
Diese Methode löste auch ein seltsames Problem, bei dem ich innerhalb von ng-repeat meine eigenen Parameter nicht an meinen Filter übergeben konnte. Egal was ich tat, sie kamen immer wieder als Index und Gesamtsammlung zurück. Durch diese Rückgabemethode konnte ich meine Parameter übergeben und trotzdem das ursprüngliche Element laden, großartige Lösung!
Dennis Smolek
Diese Antwort löste mein Problem, bei dem ich keine $ scope-Variable als Parameter an die Filterfunktion übergeben konnte. Beste Lösung. Upvoted!
Valafar
Wenn ich dies mehr als einmal positiv bewerten könnte, würde ich sicherstellen, dass es die am besten bewertete Antwort in der Geschichte von SO ist. Das nervt mich seit Jahren ... und dann finde ich die (jetzt 2 Jahre alte) Antwort ... Vielen Dank.
PKD
Noch nützlich bei 2019! Vielen Dank.
Ashilon
76

Soweit ich weiß, können Sie keine Argumente an eine Filterfunktion übergeben (wenn Sie den Filterfilter verwenden). Was Sie tun müssten, ist einen benutzerdefinierten Filter zu schreiben, etw wie folgt:

.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;
};

Hier ist die funktionierende jsFiddle: http://jsfiddle.net/pkozlowski_opensource/myr4a/1/

Die andere einfache Alternative, ohne benutzerdefinierte Filter zu schreiben, besteht darin, einen Namen zum Herausfiltern in einem Bereich zu speichern und dann zu schreiben:

$scope.weDontLike = function(item) {
  return item.name != $scope.name;
};
pkozlowski.opensource
quelle
Das ist Präfekt danke! Das Speichern des Namens im Bereich funktioniert nicht so gut, da ich drei Listen mit denselben Daten auf derselben Seite habe, die mit unterschiedlichen Status (oder Namen) filtern.
Gestaltwandler
Gibt es eine Möglichkeit, 'Adam' (bezogen auf Ihre JSFiddle) dynamisch einzustellen? Es scheint unmöglich (und ich denke, das ist absichtlich), ngModel und einen benutzerdefinierten Filter in Angular zu kombinieren ...
Rolf
Ist es möglich, die Parameter eines Filters neu zu ordnen? Übergeben Sie das Element beispielsweise an den zweiten Parameter eines Filters?
Pooya
Es ist erwähnenswert, dass in diesem Beispiel das Markup {{items | ist weDontLike: 'thenameyoudontlike'}} ... jetzt musst du zur Geige gehen, um das zu bekommen. Beachten Sie auch, dass Sie mehrere Parameter an Ihren benutzerdefinierten Filter {{items | übergeben können weDontLike: 'thename': ['I am', 'ein Array']: 'und so weiter'}} Sie würden Ihrem benutzerdefinierten Filter einfach weitere Argumente hinzufügen, um Zugriff darauf zu erhalten.
Benjamin Conant
62

Tatsächlich können Sie einen Parameter übergeben ( http://docs.angularjs.org/api/ng.filter:filter ) und benötigen dafür keine benutzerdefinierte Funktion. Wenn Sie Ihren HTML-Code wie folgt umschreiben, funktioniert dies:

<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
quelle
8
Ja. Randnotiz - wenn jemand '! Adam' heißt, bekommst du ihn wie {name: '!! Adam'}.
Honzajde
5
Sie können Arrays auch hier wie filter:['Adam', 'john']
folgt übergeben
6
jsfiddle link ist defekt.
Seregwethrin
4
! Adam ist der schlechteste Name aller Zeiten
Ben Wheeler
6
Nicht-Nicht-Adam ist offensichtlich schlimmer.
Twip
30

Sie können dies einfach in Vorlage tun

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

Im Filter

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
quelle
Dies ist die beste Antwort. Es funktioniert mit dynamischen Objekten. Dies sollte die akzeptierte Antwort sein.
Abelabbesnabi
2

Wenn Sie die Antwort von pkozlowski.opensource erweitern und die in Javascript array'sintegrierte Filtermethode verwenden, könnte dies eine hübsche Lösung sein:

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

Hier ist der jsfiddle Link .

Mehr zum Array-Filter hier .

Nasif Md. Tanjim
quelle
1

Sie können mehrere Argumente an den Winkelfilter übergeben!

Definieren meiner eckigen App und einer App-Level-Variablen -

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

Ihr Filter sieht wie folgt aus: -

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;
  }]);

Und aus HTML senden Sie Daten wie: -

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

Hier sende ich ein JSON-Objekt an den Filter. Sie können auch beliebige Daten wie Zeichenfolgen oder Zahlen senden.

Sie können auch eine dynamische Anzahl von Argumenten zum Filtern übergeben. In diesem Fall müssen Sie Argumente verwenden , um diese Argumente abzurufen.

Eine funktionierende Demo finden Sie hier. Übergeben Sie mehrere Argumente an den Winkelfilter

Partha Roy
quelle
0

Sie können einfach verwenden | filter:yourFunction:arg

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

Und in js

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