web-dev-qa-db-fra.com

Fonction de filtre personnalisée AngularJS

Dans mon contrôleur, je voudrais filtrer un tableau d'objets. Chacun de ces objets est une carte pouvant contenir des chaînes ainsi que des listes

J'ai essayé d'utiliser le format $filter('filter')(array, function) mais je ne sais pas comment accéder aux éléments individuels du tableau dans ma fonction. Voici un extrait pour montrer ce que je veux.

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

Et puis dans criteriaMatch(), je vérifierai si chaque propriété correspond

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

Je dois faire tout cela dans le contrôleur et compiler une liste de listes et les définir dans la portée. J'ai donc besoin d'accéder au $filter('filter') uniquement de cette façon. Tous les exemples que j'ai trouvés dans le réseau jusqu'à présent ont des recherches de critères statiques dans la fonction, ils ne passent pas un objet de critères et ne sont pas testés pour chaque élément du tableau.

83
user2368436

Vous pouvez l'utiliser comme ceci: http://plnkr.co/edit/vtNjEgmpItqxX5fdwtPi?p=preview

Comme vous l'avez trouvé, filter accepte la fonction de prédicat qui accepte itemby élément du tableau . Il vous suffit donc de créer une fonction de prédicat basée sur la criteria donnée.

Dans cet exemple, criteriaMatch est une fonction qui retourne un prédicat Fonction qui correspond à la criteria donnée.

modèle:

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

portée:

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

Voici un exemple d'utilisation de filter dans votre JavaScript AngularJS (plutôt que dans un élément HTML).

Dans cet exemple, nous avons un tableau d'enregistrements de pays, chacun contenant un nom et un code ISO à 3 caractères.

Nous voulons écrire une fonction qui recherchera dans cette liste un enregistrement qui correspond à un code spécifique à 3 caractères.

Voici comment nous le ferions sans en utilisant 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;
};

Yup, rien de mal à cela.

Mais voici à quoi ressemblerait la même fonction, en utilisant 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.

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

Beaucoup plus propre.

N'oubliez pas que filter renvoie un tableau à la suite (une liste d'enregistrements correspondants). Dans cet exemple, nous souhaitons renvoyer un enregistrement ou NULL.

J'espère que cela t'aides.

2
Mike Gledhill

De plus, si vous souhaitez utiliser le filtre dans votre contrôleur de la même manière, procédez comme suit:

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

Vous pourriez faire quelque chose comme:

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