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


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


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


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


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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.