Come filtrare per proprietà dell'oggetto in angularJS


139

Sto cercando di creare un filtro personalizzato in AngularJS che filtrerà un elenco di oggetti in base ai valori di una proprietà specifica. In questo caso, voglio filtrare in base alla proprietà "polarità" (possibili valori di "Positivo", "Neutro", "Negativo").

Ecco il mio codice di lavoro senza il filtro:

HTML:

<div class="total">
    <h2 id="totalTitle"></h2>
    <div>{{tweets.length}}</div>
    <div id="totalPos">{{tweets.length|posFilter}}</div>
    <div id="totalNeut">{{tweets.length|neutFilter}}</div>
    <div id="totalNeg">{{tweets.length|negFilter}}</div>
</div>

Ecco l'array "$ scope.tweets" in formato JSON:

{{created_at: "Date", text: "tweet text", user:{name: "user name", screen_name: "user       screen name", profile_image_url: "profile pic"}, retweet_count: "retweet count", polarity: "Positive"},
 {created_at: "Date", text: "tweet text", user:{name: "user name", screen_name: "user screen name", profile_image_url: "profile pic"}, retweet_count: "retweet count", polarity: "Positive"},
 {created_at: "Date", text: "tweet text", user:{name: "user name", screen_name: "user screen name", profile_image_url: "profile pic"}, retweet_count: "retweet count", polarity: "Positive"}}

Il miglior filtro che ho potuto trovare come segue:

myAppModule.filter('posFilter', function(){
return function(tweets){
    var polarity;
    var posFilterArray = [];
    angular.forEach(tweets, function(tweet){
        polarity = tweet.polarity;
        console.log(polarity);
        if(polarity==='Positive'){
              posFilterArray.push(tweet);
        }
        //console.log(polarity);
    });
    return posFilterArray;
};
});

Questo metodo restituisce un array vuoto. E nulla viene stampato dall'istruzione "console.log (polarity)". Sembra che non stia inserendo i parametri corretti per accedere alla proprietà dell'oggetto di "polarità".

Qualche idea? La tua risposta è molto apprezzata


3
Bella domanda, ma il codice potrebbe essere ridotto, gran parte di esso non è rilevante per la domanda.
setec,

Risposte:


218

Devi semplicemente usare il filterfiltro (vedi la documentazione ):

<div id="totalPos">{{(tweets | filter:{polarity:'Positive'}).length}}</div>
<div id="totalNeut">{{(tweets | filter:{polarity:'Neutral'}).length}}</div>
<div id="totalNeg">{{(tweets | filter:{polarity:'Negative'}).length}}</div>

Fiddle


1
Esiste un modo per filtrare l'elenco degli elementi passando un filtro personalizzato a un evento ng-click al di fuori dell'istruzione ng-repeat? In questo caso, voglio posizionare tre pulsanti "polarità" sopra i risultati che filtrano in base alla valutazione.
sh3nan1gans,

2
Non sono sicuro di capire. Se si desidera scegliere la polarità da filtrare, è possibile passare una variabile ambito invece di un semplice testo: filter:{polarity:polarityToFilter}dove $scope.polarityToFilterviene riempito da un clic su uno dei tre pulsanti. È questo che stai cercando di fare?
Blackhole,

Sembra che potrebbe funzionare. Tuttavia, la mia app deve anche essere in grado di eliminare singoli elementi dell'elenco.
sh3nan1gans,

Il problema con il filtro è che viene creato un nuovo array ogni volta che viene applicato un filtro che rompe il legame tra un elemento filtrato e il suo indice originale nell'array non filtrato. C'è un modo per mantenere il pareggio o ng-hide è la mia unica opzione? Ecco un tutorial per un'alternativa al filtro usando ng-hide: bennadel.com/blog/…
sh3nan1gans

ngRepeat espone una $indexproprietà sull'ambito locale che puoi anche usare.
Blackhole,

27

La documentazione ha la risposta completa. Comunque è così:

<input type="text" ng-model="filterValue">
<li ng-repeat="i in data | filter:{age:filterValue}:true"> {{i | json }}</li>

filtrerà solo agenella datamatrice ed trueè per la corrispondenza esatta.

Per il filtraggio profondo,

<li ng-repeat="i in data | filter:{$:filterValue}:true"> {{i}}</li>

Il $è una struttura speciale per il filtro profonda e la trueè per corrispondenza esatta come sopra.


Semplice e pulito.
scaryguy,

Questo filtro è integrato o deve essere scritto in Angular e AngularJS?
P Satish Patro,

23

Puoi anche farlo per renderlo più dinamico.

<input name="filterByPolarity" data-ng-model="text.polarity"/>

Quindi ng-repeat sarà simile a questo

<div class="tweet" data-ng-repeat="tweet in tweets | filter:text"></div>

Naturalmente questo filtro verrà utilizzato solo per filtrare in base alla polarità


5

Abbiamo collezione come di seguito:


inserisci qui la descrizione dell'immagine

Sintassi:

{{(Collection/array/list | filter:{Value : (object value)})[0].KeyName}}

Esempio:

{{(Collectionstatus | filter:{Value:dt.Status})[0].KeyName}}

-O-

Sintassi:

ng-bind="(input | filter)"

Esempio:

ng-bind="(Collectionstatus | filter:{Value:dt.Status})[0].KeyName"

4

Puoi provare questo. funziona per me "nome" è una proprietà in arr.

repeat="item in (tagWordOptions | filter:{ name: $select.search } ) track by $index
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.