Come posso filtrare un array con AngularJS e utilizzare una proprietà dell'oggetto filtrato come attributo ng-model?


122

Se ho un array di oggetti e voglio associare il modello Angular a una proprietà di uno degli elementi in base a un filtro, come posso farlo? Posso spiegare meglio con un esempio concreto:

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>

controller:

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

Voglio filtrare il secondo input al soggetto con un voto 'C', ma non voglio legare il modello al voto ; Voglio associarlo al titolo della materia che ha voto "C".

È possibile e, in caso affermativo, come si fa?

Risposte:


127
<div ng-repeat="subject in results.subjects | filter:{grade:'C'}">
    <input ng-model="subject.title" />
</div>

1
Vedo dove stai andando con quello, ma davvero non volevo un ripetitore. La proprietà in base alla quale filtrerò è una colonna Identity, quindi è unica. Ma vedo che questo sarebbe il modo corretto per risolvere il problema generico.
Bernhard Hofmann

1
questo è un tutorial per italiani :) dev.stasbranger.com/post/77190983049/…
Silvio Troia

10
questo è stato molto utile e per l'inverso (tutto tranne C), funzionerebbe:filter:{grade:'!'+'C'}
pulkitsinghal

2
Puoi fare lo stesso con un grade array? Nel mio caso creo il mio array di voti da un treeview e voglio filtrare il risultato per quelli nell'array.
Juan Carlos Oropeza

157

Puoi utilizzare il filtro "filtro" nel controller per ottenere tutti i voti "C". Ottenere il primo elemento della matrice dei risultati ti darà il titolo dell'argomento che ha il voto "C".

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

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

Lo stesso con ES6 semplice:

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

mi dispiace non sto seguendo quel secondo filtro ('filtro') puoi spiegarlo un po 'di più?
Winnemucca

1
@stevek Questo è il nome del filtro. Il metodo filter () ti dà il filtro. È solo che il filtro è chiamato filtro perché filtra un array. Avrebbe questo aspetto con il filtro valuta: $ filter ('currency') (amount, symbol, fractionSize) Controlla i documenti qui: docs.angularjs.org/api/ng/filter
Oliver

61

Ecco un JSBin modificato con un esempio funzionante:

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

Ecco cosa ho fatto con i filtri nell'ingresso:

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

1
Questo è il vero affare. Questo è il potere. Questo è il modo. Sono andato con questo e ora sono felice.
user1576978

13

nota, se usi $ filter in questo modo:

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

e ti è capitato di avere un altro voto per, Oh non so, CC o AC o C + o CCC li attira. devi aggiungere un requisito per una corrispondenza esatta:

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

Questo mi ha davvero ucciso quando stavo inserendo alcuni dettagli di commissione come questo:

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

vieni chiamato solo per un bug perché stava inserendo l'ID della commissione 56 anziché 6.

Aggiungendo le vere forze una corrispondenza esatta.

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

Eppure, preferisco questo (uso il dattiloscritto, da cui "Let" e =>):

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

Lo faccio perché, a un certo punto lungo la strada, potrei voler ottenere qualche informazione in più da quei dati filtrati, ecc ... avere la funzione proprio lì lascia il cofano aperto.


Ho avuto lo stesso errore come te, grazie per il suggerimento con il terzo parametro booleano. Non ne ero consapevole.
Georg Leber

12

se si desidera creare un elenco separato di risultati nel controller, è possibile applicare 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'});
}

Quindi puoi fare riferimento a FailSubjects nello stesso modo in cui faresti riferimento all'oggetto risultati

puoi leggere di più al riguardo qui https://docs.angularjs.org/guide/filter

poiché questa risposta angolare ha aggiornato la documentazione, ora consiglia di chiamare il filtro

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

cos'è filterFilter? è un servizio o una direttiva? dov'è il codice per filterFilter?
Mou

è un servizio angolare. Dai un'occhiata al primo esempio nel link sopra. (nel file scripts.js)
Kieran

anche se hanno cambiato la documentazione filterFilter funziona ancora ..
Kieran

4

Puoi anche usare funzioni con $filter('filter'):

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

4

Se stai usando ES6 puoi:

var sample = [1, 2, 3]

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

/* output */
[1, 3]

Tieni inoltre presente che il filtro non aggiorna l'array esistente, ma restituirà ogni volta un nuovo array filtrato.


0

Applicare lo stesso filtro in HTML con più colonne, solo un esempio:

 variable = (array | filter : {Lookup1Id : subject.Lookup1Id, Lookup2Id : subject.Lookup2Id} : true)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.