2013-05-15 14 views
60

Sono un newbie di AngularJS e sto costruendo una piccola applicazione di elenchi di noleggio auto proof-of-concept che attira alcuni JSON e restituisce vari bit di tali dati tramite un ng -repeat, con un paio di filtri:AngularJS: filtri personalizzati e ng-repeat

<article data-ng-repeat="result in results | filter:search" class="result"> 
     <header><h3>{{result.carType.name}}, {{result.carDetails.doors}} door, &pound;{{result.price.value}} - {{ result.company.name }}</h3></header> 
      <ul class="result-features"> 
       <li>{{result.carDetails.hireDuration}} day hire</li> 
       <li data-ng-show="result.carDetails.airCon">Air conditioning</li> 
       <li data-ng-show="result.carDetails.unlimitedMileage">Unlimited Mileage</li> 
       <li data-ng-show="result.carDetails.theftProtection">Theft Protection</li> 
      </ul> 
    </article> 

    <h2>Filters</h2> 

    <h4>Doors:</h4> 
    <select data-ng-model="search.carDetails"> 
     <option value="">All</option> 
     <option value="2">2</option> 
     <option value="4">4</option> 
     <option value="9">9</option> 
    </select> 

    <h4>Provider:</h4> 
    Atlas Choice <input type="checkbox" data-ng-model="search.company" ng-true-value="Atlas Choice" ng-false-value="" value="Atlas Choice" /><br> 
    Holiday Autos <input type="checkbox" data-ng-model="search.company" ng-true-value="Holiday Autos" ng-false-value="" value="Holiday Autos" /><br> 
    Avis <input type="checkbox" data-ng-model="search.company" ng-true-value="Avis" ng-false-value="" value="Avis" /><br>  

Ora voglio creare un filtro personalizzato nel mio controller, in grado di iterare gli articoli nel mio ng-repeat e restituire solo gli elementi che soddisfano determinati criteri - per Ad esempio, potrei creare una matrice di valori in base alla quale sono selezionate le caselle di controllo 'provider', quindi valutare ogni voce ng-repeat rispetto a quella. Non riesco proprio a capire come lo farei comunque, in termini di sintassi - qualcuno può aiutarti?

Ecco la mia Plunker: http://plnkr.co/edit/lNJNYagMC2rszbSOF95k?p=preview

risposta

139

Se si desidera eseguire una logica filtro personalizzato è possibile creare una funzione che prende l'elemento di matrice come argomento e restituisce true o false a seconda che dovrebbe essere nei risultati di ricerca. Poi passarlo alla istruzione filter proprio come si fa con l'oggetto search, ad esempio:

JS:

$scope.filterFn = function(car) 
{ 
    // Do some tests 

    if(car.carDetails.doors > 2) 
    { 
     return true; // this will be listed in the results 
    } 

    return false; // otherwise it won't be within the results 
}; 

HTML:

... 
<article data-ng-repeat="result in results | filter:search | filter:filterFn" class="result"> 
... 

Come potete vedere voi può concatenare molti filtri insieme, quindi aggiungere la funzione di filtro personalizzata non ti obbliga a rimuovere il filtro precedente usando l'oggetto search t (lavoreranno insieme senza soluzione di continuità).

+14

Questo esempio deve essere presente nei documenti. –

+14

Molto interessante! Il filtro può essere semplificato per restituire car.carDetails.doors> 2; 'comunque. – sp00m

+13

Certo che può. Ho deciso per una versione più prolissa, tuttavia, per renderla più chiara come esempio di apprendimento. – mirrormx

1

Uno dei modi più semplici per risolvere questo problema è quello di utilizzare la $, che è la ricerca tutti.

Ecco un plunker che mostra che funziona. Ho cambiato le caselle di controllo per la radio (perché ho pensato che dovrebbero essere complementari) ..

http://plnkr.co/edit/dHzvm6hR5P8G4wPuTxoi?p=preview

Se si desidera un modo molto specifico di fare questo (invece di fare una ricerca generica) è necessario lavorare con funzioni nella ricerca

La documentazione è qui

http://docs.angularjs.org/api/ng.filter:filter

28

Se si vuole ancora un filtro personalizzato è possibile passare nel modello di ricerca per il filtro:

<article data-ng-repeat="result in results | cartypefilter:search" class="result"> 

Dove definizione per il cartypefilter può assomigliare a questo:

app.filter('cartypefilter', function() { 
    return function(items, search) { 
    if (!search) { 
     return items; 
    } 

    var carType = search.carType; 
    if (!carType || '' === carType) { 
     return items; 
    } 

    return items.filter(function(element, index, array) { 
     return element.carType.name === search.carType; 
    }); 

    }; 
}); 

http://plnkr.co/edit/kBcUIayO8tQsTTjTA2vO?p=preview

+3

puoi fornire più di un parametro a un filtro personalizzato? – Vincent

4

È possibile chiamare più di 1 filtro funzione nello stesso filtro ng-repeat

<article data-ng-repeat="result in results | filter:search() | filter:filterFn()" class="result"> 
+0

possibili ai filtri OR invece di AND? – lostintranslation

+0

mmm ... Penso che la soluzione migliore è una funzione per fare questo, ecco un esempio (non funzionare) http://plnkr.co/edit/PNwyDKXk9RQcur8Tpp8w?p=preview migliore – alvarodoune

Problemi correlati