¿Cómo se filtra una matriz con AngularJS y uso una propiedad del objeto filtrado como el atributo ng-model?

Si tengo una matriz de objetos y quiero vincular el modelo angular a una propiedad de uno de los elementos basados ​​en un filtro, ¿cómo hago eso? Puedo explicar mejor con un ejemplo concreto:

HTML:

     JS Bin       

Controlador:

 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

Quiero filtrar la segunda entrada al tema con una calificación “C”, pero no quiero vincular el modelo a la calificación ; Quiero vincularlo al título de la asignatura que tiene grado ‘C’.

¿Es esto posible? De ser así, ¿cómo se hace?

 

Puede usar el filtro “filtro” en su controlador para obtener todas las calificaciones “C”. Obtener el primer elemento de la matriz de resultados le dará el título de la asignatura que tiene la calificación “C”.

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

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

Lo mismo con ES6 simple:

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

Aquí hay un JSBin modificado con una muestra de trabajo:

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

Esto es lo que hice con los filtros en la entrada:

  

si quisiera crear una lista separada de resultados en el controlador, podría aplicar un filtro

 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'}); } 

A continuación, puede hacer referencia a los sujetos fallidos de la misma manera que haría referencia al objeto de resultados

Puedes leer más sobre esto aquí https://docs.angularjs.org/guide/filter

ya que esta respuesta angular ha actualizado la documentación que ahora recomiendan llamar al filtro

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

tenga en cuenta que si usa $ filter como este:

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

y tu pasaste a tener otra calificación para, Oh no sé, CC o AC o C + o CCC, los atrae. necesita agregar un requisito para una coincidencia exacta:

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

Esto realmente me mató cuando estaba sacando algunos detalles de comisión como esta:

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

solo me llamaron por un error porque estaba ingresando la Id. de comisión 56 en vez de 6.

Agregar las verdaderas fuerzas una coincidencia exacta.

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

Sin embargo, todavía prefiero esto (uso el texto typescript, de ahí el “Let” y =>):

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

Lo hago porque, en algún punto del camino, es posible que desee obtener más información de los datos filtrados, etc … tener la función en el mismo lugar deja el capó abierto.

También puede usar funciones con $filter('filter') :

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

Aplicando el mismo filtro en HTML con múltiples columnas, solo ejemplo:

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

Si está utilizando ES6, puede:

 var sample = [1, 2, 3] var result = sample.filter(elem => elem !== 2) /* output */ [1, 3] 

También tenga en cuenta que el filtro no actualiza la matriz existente, sino que devolverá una nueva matriz filtrada cada vez.