Funzione di filtro personalizzato AngularJS


91

All'interno del mio controller, vorrei filtrare un array di oggetti. Ciascuno di questi oggetti è una mappa che può contenere sia stringhe che elenchi

Ho provato a utilizzare il $filter('filter')(array, function)formato ma non so come accedere ai singoli elementi dell'array all'interno della mia funzione. Ecco uno snippet per mostrare quello che voglio.

$filter('filter')(array, function() {
  return criteriaMatch(item, criteria);
});

E poi in criteriaMatch(), controllerò se ciascuna delle singole proprietà corrisponde

var criteriaMatch = function(item, criteria) {
  // go thro each individual property in the item and criteria
  // and check if they are equal
}

Devo fare tutto questo nel controller e compilare un elenco di elenchi e impostarli nell'ambito. Quindi devo accedere $filter('filter')solo in questo modo. Tutti gli esempi che ho trovato finora in rete hanno ricerche di criteri statici all'interno della funzione, non passano un oggetto criteri e testano ogni elemento nell'array.


3
Perché hai bisogno di un filtro? Di solito vengono utilizzati filtri dai modelli. Non puoi semplicemente avere una semplice funzione nel tuo controller se la stai usando solo da lì?
Ketan

invece di passare manualmente attraverso ogni elemento dell'array, ho pensato che avremmo potuto usare la funzionalità $ filter ('filter') di angular (che si occuperà di iterare ogni elemento se specifichiamo solo la funzione predicate)
user2368436

Risposte:


173

Puoi usarlo in questo modo: http://plnkr.co/edit/vtNjEgmpItqxX5fdwtPi?p=preview

Come hai scoperto, filteraccetta la funzione predicato che accetta elemento per elemento dall'array. Quindi, devi solo creare una funzione predicato basata sul dato criteria.

In questo esempio, criteriaMatchè una funzione che restituisce una funzione predicato che corrisponde al dato criteria.

modello:

<div ng-repeat="item in items | filter:criteriaMatch(criteria)">
  {{ item }}
</div>

scopo:

$scope.criteriaMatch = function( criteria ) {
  return function( item ) {
    return item.name === criteria.name;
  };
};

Non userò questa funzione di corrispondenza dei criteri dall'html .. come la chiamerò dall'interno del controller è corretto? $ filtro ('filtro') (array, funzione () {return criteriMatch (elemento, criteri);});
user2368436

6
Se non lo stai utilizzando nel tuo modello, la definizione del filtro non ti dà alcun vantaggio. Puoi semplicemente definire una semplice funzione javascript, poiché è ancora più breve lì. È possibile utilizzare il filtermetodo nativo nell'oggetto Array:array.filter(function(item){return item.name === criteria.name;})
Tosh

Ho una funzione javascript. volevo solo assicurarmi che angular non avesse un modo più semplice per farlo .. accetterò la tua risposta. grazie.
user2368436

2

Ecco un esempio di come filteruseresti all'interno del tuo JavaScript AngularJS (piuttosto che in un elemento HTML).

In questo esempio, abbiamo una matrice di record Paese, ciascuno contenente un nome e un codice ISO di 3 caratteri.

Vogliamo scrivere una funzione che cercherà in questo elenco un record che corrisponde a uno specifico codice di 3 caratteri.

Ecco come lo faremmo senza usare filter:

$scope.FindCountryByCode = function (CountryCode) {
    //  Search through an array of Country records for one containing a particular 3-character country-code.
    //  Returns either a record, or NULL, if the country couldn't be found.
    for (var i = 0; i < $scope.CountryList.length; i++) {
        if ($scope.CountryList[i].IsoAlpha3 == CountryCode) {
            return $scope.CountryList[i];
        };
    };
    return null;
};

Sì, niente di sbagliato in questo.

Ma ecco come apparirebbe la stessa funzione, usando filter:

$scope.FindCountryByCode = function (CountryCode) {
    //  Search through an array of Country records for one containing a particular 3-character country-code.
    //  Returns either a record, or NULL, if the country couldn't be found.

    var matches = $scope.CountryList.filter(function (el) { return el.IsoAlpha3 == CountryCode; })

    //  If 'filter' didn't find any matching records, its result will be an array of 0 records.
    if (matches.length == 0)
        return null;

    //  Otherwise, it should've found just one matching record
    return matches[0];
};

Molto più ordinato.

Ricordati che filter restituisce un array come risultato (un elenco di record corrispondenti), quindi in questo esempio, vorremo restituire 1 record o NULL.

Spero che questo ti aiuti.


0

Inoltre, se desideri utilizzare il filtro nel controller nello stesso modo in cui lo fai qui:

<div ng-repeat="item in items | filter:criteriaMatch(criteria)">
  {{ item }}
</div>

Potresti fare qualcosa come:

var filteredItems =  $scope.$eval('items | filter:filter:criteriaMatch(criteria)');

6
In alternativa,var filteredItems = $filter('criteriaMatch')(items, criteria);
321zeno
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.