Przekazywanie argumentów do filtrów angularjs

99

Czy jest możliwe przekazanie argumentu do funkcji filtrującej, aby można było filtrować według dowolnej nazwy?

Coś jak

$scope.weDontLike = function(item, name) {
    console.log(arguments);
    return item.name != name;
};
zmiennokształtny
źródło

Odpowiedzi:

223

Właściwie istnieje inne (być może lepsze rozwiązanie), w którym można użyć natywnego filtru „filtru” angulara i nadal przekazywać argumenty do własnego filtru.

Rozważ następujący kod:

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

Aby to zadziałało, po prostu zdefiniuj swój filtr w następujący sposób:

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

Jak widać tutaj, weDontLike w rzeczywistości zwraca inną funkcję, która ma twój parametr w swoim zakresie, a także oryginalny element pochodzący z filtra.

Zajęło mi 2 dni, zanim zdałem sobie sprawę, że możesz to zrobić, nigdzie jeszcze nie widziałem tego rozwiązania.

Zamówienie Odwrócona polaryzacja filtrem angularjs aby zobaczyć, jak można to wykorzystać dla innych przydatnych operacji z filtrem.

Denis Pshenov
źródło
Jeśli twój filtr wymaga wielu argumentów, zobacz Jak wywołać filtr Angular.js z wieloma argumentami?
nh2
Ta metoda rozwiązała również dziwny problem, w którym wewnątrz funkcji ng-repeat nie mogłem przekazać własnych parametrów do mojego filtra. Bez względu na to, co zrobiłem, zawsze wracały jako indeks i ogólna kolekcja. Wykonując tę ​​metodę zwrotu, mogłem przekazać moje parametry i nadal ładować oryginalny element, świetna naprawa!
Dennis Smolek
Ta odpowiedź rozwiązała mój problem, w którym nie mogłem przekazać zmiennej $ scope jako parametru do funkcji filtrującej. NAJLEPSZE rozwiązanie. Głosowano!
valafar
Gdybym mógł zagłosować za tym więcej niż raz, upewniłbym się, że była to najbardziej pozytywna odpowiedź w historii SO. To mnie wkurza od lat ... i wtedy znajduję odpowiedź (teraz 2-latka) ... Dziękuję bardzo bardzo.
PKD
Nadal przydatne w 2019! Wielkie dzięki.
ashilon
76

Z tego, co rozumiem, nie można przekazywać argumentów do funkcji filtrującej (podczas korzystania z filtru „filter”). To, co musiałbyś zrobić, to napisać niestandardowy filtr, coś takiego:

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

Oto działający jsFiddle: http://jsfiddle.net/pkozlowski_opensource/myr4a/1/

Inną prostą alternatywą, bez pisania niestandardowych filtrów, jest przechowywanie nazwy do odfiltrowania w zakresie, a następnie napisanie:

$scope.weDontLike = function(item) {
  return item.name != $scope.name;
};
pkozlowski.opensource
źródło
To doskonałe dzięki! Przechowywanie nazwy w zakresie nie będzie działać tak dobrze, ponieważ mam trzy listy z tych samych danych na tej samej stronie, filtrując je z różnymi stanami (lub nazwami).
Shapeshifter
jakikolwiek, aby ustawić „Adam” (odnosząc się do twojego JSFiddle) dynamicznie? wydaje się niemożliwe (i myślę, że jest to celowe) połączenie ngModel i niestandardowego filtra w Angular ...
Rolf
Czy można zmienić kolejność parametrów filtra? Na przykład przekazać element do drugiego parametru filtru?
Pooya,
Warto zauważyć, że w tym przykładzie znacznik to {{items | weDontLike: 'thenameyoudontlike'}} ... w tej chwili musisz iść na skrzypce, aby to zdobyć. Warto również zauważyć, że możesz przekazać wiele parametrów do własnego filtra {{items | weDontLike: 'thename': ['Jestem', 'tablica']: 'i tak dalej'}} po prostu dodasz więcej argumentów do własnego filtra, aby mieć do nich dostęp.
Benjamin Conant
62

Właściwie możesz przekazać parametr ( http://docs.angularjs.org/api/ng.filter:filter ) i nie potrzebujesz do tego niestandardowej funkcji. Jeśli przepiszesz swój HTML jak poniżej, zadziała:

<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
źródło
8
Tak. Uwaga dodatkowa - jeśli ktoś ma na imię „! Adam”, dostajesz go jak {imię: „!! Adam”}.
honzajde
5
Możesz tu również przekazywać tablice w ten sposóbfilter:['Adam', 'john']
iConnor,
6
jsfiddle link jest uszkodzony.
Seregwethrin
4
! Adam to najgorsze nazwisko w historii
Ben Wheeler
6
Nie-nie-Adam jest oczywiście gorszy.
twip
30

Możesz po prostu zrobić to w szablonie

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

W filtrze

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
źródło
To najlepsza odpowiedź. Działa z dynamicznymi obiektami. To powinna być akceptowana odpowiedź.
abelabbesnabi
2

Rozszerzając odpowiedź pkozlowski.opensource i używając array'smetody wbudowanego filtru javascript, można by uprzyjemnić rozwiązanie:

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

Oto link jsfiddle .

Więcej o filtrze Array tutaj .

Nasif Md. Tanjim
źródło
1

Możesz przekazać wiele argumentów do filtra kątowego!

Definiowanie mojej aplikacji kątowej i zmiennej poziomu aplikacji -

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

Twój filtr będzie wyglądał następująco: -

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

A z HTML wyślesz dane takie jak: -

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

Tutaj wysyłam obiekt JSON do filtra. Możesz również wysłać dowolne dane, takie jak ciąg lub liczba.

możesz również przekazać dynamiczną liczbę argumentów do filtrowania, w takim przypadku musisz użyć argumentów, aby uzyskać te argumenty.

Aby zobaczyć działające demo, przejdź tutaj - przekazywanie wielu argumentów do filtra kątowego

Partha Roy
źródło
0

Możesz po prostu użyć | filter:yourFunction:arg

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

A w js

$scope.weDontLike = function(group) {
//here your condition/criteria
return !!group 
}
user2972221
źródło