web-dev-qa-db-fra.com

Comment filtrer un tableau avec AngularJS et utiliser une propriété de l'objet filtré en tant qu'attribut ng-model?

Si j'ai un tableau d'objets et que je veux lier le modèle Angular à une propriété de l'un des éléments en fonction d'un filtre, comment puis-je le faire? Je peux mieux expliquer avec un exemple concret:

HTML:

<!DOCTYPE html>
<html ng-app>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
        <meta charset=utf-8 />
        <title>JS Bin</title>
    </head>
    <body ng-controller="MyCtrl">
        <input ng-model="results.year">
        <input ng-model="results.subjects.title | filter:{grade:'C'}">
    </body>
</html>

Manette:

function MyCtrl($scope) {
  $scope.results = {
    year:2013,
    subjects:[
      {title:'English',grade:'A'},
      {title:'Maths',grade:'A'},
      {title:'Science',grade:'B'},
      {title:'Geography',grade:'C'}
    ]
  };
}

JSBin: http://jsbin.com/adisax/1/edit

Je veux filtrer la deuxième entrée du sujet avec une note 'C', mais je ne veux pas lier le modèle à la note grade ; Je veux le lier au titre de la matière de niveau 'C'.

Est-ce possible, et si oui, comment fait-on?

117
Bernhard Hofmann
<div ng-repeat="subject in results.subjects | filter:{grade:'C'}">
    <input ng-model="subject.title" />
</div>
123
JB Nizet

Vous pouvez utiliser le filtre "filtre" de votre contrôleur pour obtenir tous les grades "C". Obtenir le premier élément du tableau de résultats vous donnera le titre de la matière qui a la note "C".

$scope.gradeC = $filter('filter')($scope.results.subjects, {grade: 'C'})[0];

http://jsbin.com/ewitun/1/edit

La même chose avec la plaine ES6:

$scope.gradeC = $scope.results.subjects.filter((subject) => subject.grade === 'C')[0]
152
Oliver

Voici un JSBin modifié avec un exemple de travail:

http://jsbin.com/sezamuja/1/edit

Voici ce que j'ai fait avec les filtres dans l'entrée:

<input ng-model="(results.subjects | filter:{grade:'C'})[0].title">
59
lukeatdesignworks

notez s'il vous plaît que si vous utilisez $ filter comme ceci:

$scope.failedSubjects = $filter('filter')($scope.results.subjects, {'grade':'C'});

et vous avez eu une autre note pour, Oh je ne sais pas, CC ou AC ou C + ou CCC il les attire. vous devez ajouter une exigence pour une correspondance exacte:

$scope.failedSubjects = $filter('filter')($scope.results.subjects, {'grade':'C'}, true);

Cela m’a vraiment tué lorsque j’ai recueilli certains détails de la commission comme celui-ci:

var obj = this.$filter('filter')(this.CommissionTypes, { commission_type_id: 6}))[0];

seulement être appelé pour un bogue parce qu'il attirait l'ID de commission 56 plutôt que 6.

Ajouter le vrai force une correspondance exacte.

var obj = this.$filter('filter')(this.CommissionTypes, { commission_type_id: 6}, true))[0];

Pourtant, je préfère ceci (j'utilise TypeScript, d'où les "Let" et =>):

let obj = this.$filter('filter')(this.CommissionTypes, (item) =>{ 
             return item.commission_type_id === 6;
           })[0];

Je le fais parce que, à un moment donné, je souhaiterais peut-être obtenir plus d’informations à partir des données filtrées, etc.

12
Daniel Morris

si vous voulez créer une liste séparée de résultats dans le contrôleur, vous pouvez appliquer un filtre.

function MyCtrl($scope, filterFilter) {
  $scope.results = {
    year:2013,
    subjects:[
      {title:'English',grade:'A'},
      {title:'Maths',grade:'A'},
      {title:'Science',grade:'B'},
      {title:'Geography',grade:'C'}
    ]
  };
  //create a filtered array of results 
  //with grade 'C' or subjects that have been failed
  $scope.failedSubjects = filterFilter($scope.results.subjects, {'grade':'C'});
}

Ensuite, vous pouvez référencer failedSubjects de la même manière que vous référeriez le résultats objet

vous pouvez en savoir plus à ce sujet ici https://docs.angularjs.org/guide/filter

depuis cette réponse angular ont mis à jour la documentation, ils recommandent maintenant d'appeler le filtre

// update 
// eg: $filter('filter')(array, expression, comparator, anyPropertyKey);
// becomes
$scope.failedSubjects = $filter('filter')($scope.results.subjects, {'grade':'C'});
11
Kieran

Si vous utilisez ES6, vous pouvez:

var sample = [1, 2, 3]

var result = sample.filter(elem => elem !== 2)

/* output */
[1, 3]

Notez également que le filtre ne met pas à jour le tableau existant, il retournera un nouveau tableau filtré à chaque fois.

3
Diego Venâncio

Vous pouvez également utiliser fonctions avec $filter('filter'):

var foo = $filter('filter')($scope.results.subjects, function (item) {
  return item.grade !== 'A';
});
2
Nelu

Appliquer le même filtre en HTML avec plusieurs colonnes, juste un exemple:

 variable = (array | filter : {Lookup1Id : subject.Lookup1Id, Lookup2Id : subject.Lookup2Id} : true)
0
Amay Kulkarni