2013-05-15 11 views
60

Ich bin ein AngularJS-Neuling und ich baue eine kleine Proof-of-Concept-Mietwagen-App, die einige JSON einzieht und verschiedene Bits dieser Daten über eine ng ausgibt -repeat, mit ein paar Filter:AngularJS: Benutzerdefinierte Filter und 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>  

Jetzt möchte ich einen benutzerdefinierten Filter in meinem Controller erstellen, die über die Einzelteile in meinem ng-repeat laufen kann und geben nur die Elemente, die bestimmte Kriterien erfüllen - für Beispiel: Ich könnte ein Array von Werten erstellen, anhand derer die Checkboxen "Anbieter" überprüft werden, und dann jedes Element mit wiederholter Ausführung dagegen evaluieren. Ich kann einfach nicht herausfinden, wie ich das machen würde, in Bezug auf die Syntax - kann mir jemand helfen?

Hier ist meine Plunker: http://plnkr.co/edit/lNJNYagMC2rszbSOF95k?p=preview

Antwort

139

Wenn Sie einige benutzerdefinierte Filterlogik ausführen möchten Sie eine Funktion erstellen können, die das Array-Element als Argument übernimmt und true oder false gibt basierend darauf, ob es sein sollte in den Suchergebnissen. geben sie dann an die filter Anweisung genau wie Sie mit dem search Objekt zu tun, zum Beispiel:

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"> 
... 

Wie Sie können Sie sehen, kann viele Filter miteinander verketten, so dass Sie durch das Hinzufügen Ihrer benutzerdefinierten Filterfunktion nicht gezwungen werden, den vorherigen Filter mit dem Objekt search zu entfernen t (sie werden nahtlos zusammenarbeiten).

+14

Dieses Beispiel sollte in der Dokumentation sein. –

+14

Sehr interessant! Der Filter kann jedoch vereinfacht werden, um car.carDetails.doors> 2; 'zurückzugeben. – sp00m

+13

Natürlich kann es. Ich habe mich jedoch für eine ausführlichere Version entschieden, um es als Lernbeispiel klarer zu machen. – mirrormx

1

Eine der einfachsten Möglichkeiten, um dieses Problem beheben die $ zu verwenden ist, die alle die Suche ist.

Hier ist ein Plünderer, der es funktioniert zeigt. Ich habe die Kontrollkästchen, um Radio geändert (weil ich dachte, sie sollten sich ergänzen) ..

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

Wenn Sie eine ganz bestimmte Art und Weise wollen, dies zu tun (statt eine generische Suche zu tun) benötigen Sie mit Funktionen arbeiten bei der Suche.

Die Dokumentation ist hier

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

28

Wenn Sie noch einen benutzerdefinierten Filter in das Suchmodell den Filter passieren kann:

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

Wo Definition für die cartypefilter wie folgt aussehen:

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

können Sie einem benutzerdefinierten Filter mehr als einen Parameter geben? – Vincent

4

Sie können mehr als 1 Funktionsfilter im selben ng-Wiederholungsfilter aufrufen

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

möglich, OR-Filter anstelle von UND? – lostintranslation

+0

mmm ... Ich denke, die beste Option eine Funktion, dass hier zu tun ist, ist ein Beispiel (nicht) http://plnkr.co/edit/PNwyDKXk9RQcur8Tpp8w?p=preview beste – alvarodoune