Passaggio di argomenti ai filtri angularjs


99

È possibile passare un argomento alla funzione di filtro in modo da poter filtrare in base a qualsiasi nome?

Qualcosa di simile a

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

Risposte:


223

In realtà c'è un'altra (forse soluzione migliore) in cui puoi usare il filtro "filtro" nativo di angular e comunque passare argomenti al tuo filtro personalizzato.

Considera il codice seguente:

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

Per fare in modo che funzioni, è sufficiente definire il filtro come segue:

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

Come puoi vedere qui, weDontLike restituisce effettivamente un'altra funzione che ha il tuo parametro nel suo ambito così come l'elemento originale proveniente dal filtro.

Mi ci sono voluti 2 giorni per rendermi conto che puoi farlo, non ho ancora visto questa soluzione da nessuna parte.

Checkout inversione di polarità di un filtro angular.js per vedere come è possibile utilizzare questo per altre operazioni utili con filtro.


Nel caso in cui il tuo filtro abbia bisogno di più argomenti, vedi Come posso chiamare un filtro Angular.js con più argomenti?
nh2

Questo metodo ha anche risolto uno strano problema in cui all'interno di ng-repeat non potevo passare i miei parametri al mio filtro. Non importa cosa facessi, continuavano a tornare come indice e raccolta complessiva. Facendo questo metodo di ritorno sono stato in grado di passare i miei parametri e caricare ancora l'elemento originale, ottima soluzione!
Dennis Smolek

Questa risposta ha risolto il mio problema per cui non ero in grado di passare una variabile $ scope come parametro alla funzione di filtro. Soluzione migliore. Votato!
valafar

Se potessi votare a favore più di una volta, mi assicurerei che sia la risposta più votata nella storia di SO. Questo mi ha infastidito per anni ... e poi ho trovato la risposta (che ora ha 2 anni) ... Grazie mille.
PKD

Ancora utile al 2019! Molte grazie.
ashilon

76

Da quello che ho capito non puoi passare argomenti a una funzione di filtro (quando usi il filtro 'filtro'). Quello che dovresti fare è scrivere un filtro personalizzato, in questo modo:

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

Ecco il jsFiddle funzionante: http://jsfiddle.net/pkozlowski_opensource/myr4a/1/

L'altra semplice alternativa, senza scrivere filtri personalizzati, è memorizzare un nome da filtrare in un ambito e quindi scrivere:

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

Quello è grazie perfetti! La memorizzazione del nome nell'ambito non funzionerà così bene poiché ho tre elenchi degli stessi dati sulla stessa pagina che filtrano con stati (o nomi) diversi.
mutaforma

qualsiasi per impostare "Adam" (riferito al tuo JSFiddle) dinamicamente? sembra impossibile (e credo che sia apposta) combinare ngModel e un filtro personalizzato in Angular ...
Rolf

È possibile riordinare i parametri di un filtro? Ad esempio passare l'elemento al secondo parametro di un filtro?
Pooya

Vale la pena notare che in questo esempio il markup è {{items | weDontLike: 'thenameyoudontlike'}} ... in questo momento devi suonare il violino per capirlo. Vale anche la pena notare che puoi passare più parametri al tuo filtro personalizzato {{items | weDontLike: 'thename': ['I am', 'an array']: 'e così via'}} dovresti semplicemente aggiungere più argomenti al tuo filtro personalizzato per accedervi.
Benjamin Conant

62

In realtà puoi passare un parametro ( http://docs.angularjs.org/api/ng.filter:filter ) e non hai bisogno di una funzione personalizzata solo per questo. Se riscrivi il tuo HTML come di seguito, funzionerà:

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


8
Sì. Nota a margine: se il nome di qualcuno è "! Adam", lo ottieni come {name: "!! Adam"}.
honzajde

5
Puoi anche passare gli array anche qui in questo modofilter:['Adam', 'john']
iConnor

6
Il collegamento jsfiddle è interrotto.
Seregwethrin,

4
! Adam è il peggior nome di sempre
Ben Wheeler

6
Non-Non-Adam è ovviamente peggio.
twip

30

Puoi semplicemente fare così In Template

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

In filtro

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

Questa è la migliore risposta. Funziona con oggetti dinamici. Questa dovrebbe essere la risposta accettata.
abelabbesnabi

2

Estendendo la risposta di pkozlowski.opensource e utilizzando il array'smetodo di filtro integrato javascript , una soluzione ottimizzata potrebbe essere questa:

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

Ecco il collegamento jsfiddle .

Maggiori informazioni sul filtro Array qui .


1

Puoi passare più argomenti al filtro angolare!

Definizione della mia app angolare e di una variabile a livello di app -

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

Il tuo filtro sarà come: -

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

E dall'HTML invierai dati come: -

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

Qui sto inviando un oggetto JSON al filtro. Puoi anche inviare qualsiasi tipo di dato come stringa o numero.

inoltre puoi passare un numero dinamico di argomenti al filtro, in tal caso devi usare gli argomenti per ottenere quegli argomenti.

Per una demo funzionante, vai qui: passare più argomenti al filtro angolare


0

Puoi semplicemente usare | filter:yourFunction:arg

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

E in js

$scope.weDontLike = function(group) {
//here your condition/criteria
return !!group 
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.