web-dev-qa-db-ger.com

AngularJS benutzerdefinierte Filterfunktion

In meinem Controller möchte ich ein Array von Objekten filtern. Jedes dieser Objekte ist eine Karte, die sowohl Strings als auch Listen enthalten kann

Ich habe versucht, das $filter('filter')(array, function)-Format zu verwenden, aber ich weiß nicht, wie ich auf die einzelnen Elemente des Arrays innerhalb meiner Funktion zugreifen kann. Hier ist ein Ausschnitt, um zu zeigen, was ich will.

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

Und dann werde ich in der criteriaMatch() prüfen, ob die einzelnen Eigenschaften übereinstimmen

var criteriaMatch = function(item, criteria) {
  // go thro each individual property in the item and criteria
  // and check if they are equal
}

Ich muss all dies im Controller erledigen, eine Liste von Listen erstellen und sie in den Geltungsbereich setzen. Ich muss also nur auf diese Weise auf die $filter('filter') zugreifen. Bei allen Beispielen, die ich bisher im Netz gefunden habe, gibt es statische Kriterien innerhalb der Funktion. Sie übergeben kein Kriterienobjekt und testen mit jedem Element im Array.

83
user2368436

Sie können es wie folgt verwenden: http://plnkr.co/edit/vtNjEgmpItqxX5fdwtPi?p=preview

Wie Sie gefunden haben, akzeptiert filter eine Prädikatsfunktion, die itemby aus dem Array ..__ akzeptiert. Sie müssen also nur eine Prädikatsfunktion erstellen, die auf der angegebenen criteria basiert.

In diesem Beispiel ist criteriaMatch eine Funktion, die ein Prädikat Zurückgibt, das mit der angegebenen criteria übereinstimmt.

vorlage:

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

umfang:

$scope.criteriaMatch = function( criteria ) {
  return function( item ) {
    return item.name === criteria.name;
  };
};
165
Tosh

Hier ein Beispiel, wie Sie filter in Ihrem AngularJS-JavaScript (anstatt in einem HTML-Element) verwenden.

In diesem Beispiel haben wir ein Array von Country-Datensätzen, die jeweils einen Namen und einen dreistelligen ISO-Code enthalten.

Wir möchten eine Funktion schreiben, die diese Liste nach einem Datensatz durchsucht, der einem bestimmten dreistelligen Code entspricht.

So würden wir es machen ohne mit 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;
};

Ja, daran ist nichts falsch.

Aber so sieht die gleiche Funktion mit filter aus:

$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];
};

Viel ordentlicher.

Denken Sie daran, dass filter ein Array als Ergebnis (eine Liste übereinstimmender Datensätze) zurückgibt. In diesem Beispiel möchten wir entweder einen Datensatz oder NULL zurückgeben.

Hoffe das hilft.

2
Mike Gledhill

Außerdem, wenn Sie den Filter in Ihrem Controller auf die gleiche Weise verwenden möchten, wie Sie es hier tun:

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

Sie könnten so etwas tun:

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