2013-05-10 37 views
76

All'interno del mio controller, vorrei filtrare una serie di oggetti. Ognuno di questi oggetti è una mappa che può contenere stringhe e listeFunzione filtro personalizzato AngularJS

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

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

E poi nel criteriaMatch(), controllerò se ciascuna delle proprietà individuale partite

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 una lista di liste e metterli in scopo. Quindi ho bisogno di accedere allo $filter('filter') solo in questo modo. Tutti gli esempi che ho trovato finora nella rete hanno ricerche di criteri statici all'interno della funzione, non passano un oggetto criteri e non provano contro ogni elemento dell'array.

+3

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

+0

invece di andare manualmente attraverso ogni elemento dell'array, ho pensato che potremmo usare la funzionalità $ filter ('filter') di angular (che si occuperà di iterare ogni elemento se si specifica solo la funzione predicato) – user2368436

risposta

154

Si può usare in questo modo: http://plnkr.co/edit/vtNjEgmpItqxX5fdwtPi?p=preview

Come hai trovato, filter accetta funzione predicato che accetta voce per voce dalla matrice. Quindi, è sufficiente creare una funzione di predicato basata sul dato criteria.

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

modello:

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

portata:

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

Non lo farò stare usando questo criterio. La funzione di lettura da html .. come la chiamo dall'interno del controller è corretta? $ filter ('filter') (array, function() {return criteriaMatch (item, criteria);}); – user2368436

+5

Se non lo si utilizza nel modello, la definizione del filtro non offre alcun vantaggio. Puoi semplicemente definire una semplice funzione javascript, poiché è ancora più breve. È possibile utilizzare il metodo 'filter' nativo nell'oggetto Array:' array.filter (function (item) {return item.name === criteria.name;}) ' – Tosh

+0

Ho una funzione javascript. volevo solo assicurarmi che l'angolare non avesse un modo più semplice di farlo ... accetterò la tua risposta. grazie. – user2368436

0

Inoltre, se si desidera utilizzare il filtro nel controller stesso modo si fa qui:

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

È potrebbe fare qualcosa come:

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

In alternativa, 'var filteredItems = $ filter ('criteriaMatch') (items, criteria);' – 321zeno

2

Ecco un esempio di come utilizzare filter all'interno del codice JavaScript di AngularJS (anziché 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 un codice di 3 caratteri specifico.

Ecco come faremmo lo senza utilizzare 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; 
}; 

Yup, niente di male.

Ma ecco come la stessa funzione apparirebbe, utilizzando 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.

Ricordare che filter restituisce una matrice come risultato (un elenco di record corrispondenti), quindi in questo esempio, o si desidera restituire 1 record o NULL.

Spero che questo aiuti.

Problemi correlati