AngularJS: Benutzerdefinierte Filter und ng-repeat

70

Ich bin ein AngularJS-Neuling und baue eine kleine Proof-of-Concept-App für Mietwagenlisten auf, die JSON einbindet und verschiedene Teile dieser Daten über eine ng-Wiederholung mit ein paar Filtern wiedergibt:

   <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 in meinem Controller einen benutzerdefinierten Filter erstellen, der die Elemente in meiner ng-Wiederholung durchlaufen und nur die Elemente zurückgeben kann, die bestimmte Kriterien erfüllen. Beispielsweise kann ich ein Array von Werten erstellen, basierend auf den Kontrollkästchen "Anbieter" überprüft werden, dann bewerten Sie jedes ng-repeat-Element dagegen. Ich kann einfach nicht herausfinden, wie ich das in Bezug auf die Syntax machen würde - kann jemand helfen?

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

ParkerDigital
quelle
Versuchen Sie dieses benutzerdefinierte Filter-Tutorial freakyjolly.com/angularjs-exact-filter-match-in-values
Code Spy

Antworten:

165

Wenn Sie eine benutzerdefinierte Filterlogik ausführen möchten, können Sie eine Funktion erstellen, die das Array-Element als Argument verwendet und zurückgibt trueoder darauf falsebasiert, ob es in den Suchergebnissen enthalten sein soll. Übergeben Sie es dann filtergenau wie beim searchObjekt an die Anweisung , 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 sehen, können Sie viele Filter miteinander verketten. Wenn Sie also Ihre benutzerdefinierte Filterfunktion hinzufügen, müssen Sie den vorherigen Filter nicht mithilfe des searchObjekts entfernen (sie arbeiten nahtlos zusammen).

Mirrormx
quelle
15
Sehr interessant! Der Filter kann jedoch vereinfacht werden return car.carDetails.doors > 2;.
sp00m
14
Natürlich kann es. Ich habe mich jedoch für eine ausführlichere Version entschieden, um sie als Lernbeispiel klarer zu machen.
Mirrormx
2
Wenn Sie komplexere Filter benötigen, können Sie Ihren Filtern auch mehr als ein Argument übergeben .
nh2
@mirrimx Ich habe nicht bekommen, wann diese Funktion aufgerufen wird?
Anam
2
Ich magreturn (car.carDetails.doors > 2);
Daniel
34

Wenn Sie weiterhin einen benutzerdefinierten Filter wünschen, können Sie das Suchmodell an den Filter übergeben:

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

Wo die Definition für den Kartypefilter folgendermaßen aussehen kann:

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

Orjan
quelle
4
Können Sie einem benutzerdefinierten Filter mehr als einen Parameter zuweisen?
Vincent
6

Sie können mehrere von 1 Funktionsfiltern im selben ng-repeat-Filter aufrufen

<article data-ng-repeat="result in results | filter:search() | filter:filterFn()" class="result">
alvarodoune
quelle
möglich ODER-Filter anstelle von UND?
Verlorene Übersetzung
mmm ... ich denke, die beste Option ist eine Funktion, um das zu tun, hier ist ein Beispiel (nicht funktioniert) plnkr.co/edit/PNwyDKXk9RQcur8Tpp8w?p=preview best
alvarodoune
2

Eine der einfachsten Möglichkeiten, dies zu beheben, ist die Verwendung $der Suchfunktion.

Hier ist ein Plunker, der zeigt, wie es funktioniert. Ich habe die Kontrollkästchen auf 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 möchten (anstatt eine generische Suche durchzuführen), müssen Sie mit Funktionen in der Suche arbeiten.

Die Dokumentation finden Sie hier

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

Ganaraj
quelle