Jak filtrować według właściwości obiektu w angularJS

139

Próbuję utworzyć niestandardowy filtr w AngularJS, który będzie filtrował listę obiektów według wartości określonej właściwości. W tym przypadku chcę filtrować według właściwości „polaryzacja” (możliwe wartości „dodatnie”, „neutralne”, „ujemne”).

Oto mój działający kod bez filtra:

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>

Oto tablica „$ scope.tweets” w formacie 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"}}

Najlepszy filtr, jaki mogłem wymyślić, to:

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

Ta metoda zwraca pustą tablicę. I nic nie jest drukowane z instrukcji „console.log (polarity)”. Wygląda na to, że nie wstawiam poprawnych parametrów, aby uzyskać dostęp do właściwości obiektu „polaryzacja”.

Jakieś pomysły? Twoja odpowiedź jest bardzo doceniana.

sh3nan1gans
źródło
3
Ładne pytanie, ale kod można by zredukować, duża jego część nie jest związana z pytaniem.
setec

Odpowiedzi:

218

Wystarczy użyć filterfiltra (patrz dokumentacja ):

<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

Czarna dziura
źródło
1
Czy istnieje sposób na filtrowanie listy pozycji przez przekazanie niestandardowego filtru do zdarzenia ng-click poza instrukcją ng-repeat? W tym przypadku chcę umieścić trzy przyciski „polaryzacja” nad wynikami filtrującymi na podstawie oceny.
sh3nan1gans
2
Nie jestem pewien, czy rozumiem. Jeśli chcesz wybrać polaryzację do filtrowania, możesz przekazać zmienną zasięgu zamiast zwykłego tekstu: filter:{polarity:polarityToFilter}gdzie $scope.polarityToFilterjest wypełniana przez kliknięcie jednego z trzech przycisków. Czy to właśnie próbujesz zrobić?
Blackhole
Wydaje się, że to może zadziałać. Jednak moja aplikacja musi mieć również możliwość usuwania poszczególnych elementów listy.
sh3nan1gans
Problem z filtrowaniem polega na tym, że za każdym razem, gdy stosowany jest filtr, tworzona jest nowa tablica, która zrywa powiązanie między przefiltrowanym elementem a jego oryginalnym indeksem w niefiltrowanej tablicy. Czy jest sposób, aby utrzymać krawat, czy też ng-hide jest moją jedyną opcją? Oto samouczek dotyczący alternatywy dla filtrowania przy użyciu ng-hide: bennadel.com/blog/…
sh3nan1gans
ngRepeat ujawnia $indexwłaściwość w zakresie lokalnym, której możesz również użyć.
Blackhole
27

Dokumentacja ma pełną odpowiedź. Zresztą tak to się robi:

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

będzie filtrować tylko agew datatablicy i truesłuży do dokładnego dopasowania.

Do głębokiego filtrowania,

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

$Jest szczególnym miejscem dla głębokim filtrze i truejest dokładnym mecz jak powyżej.

Abel Terefe
źródło
Proste i czyste.
scaryguy
Czy ten filtr jest wbudowany, czy też musi być napisany w obu Angular i AngularJS?
P Satish Patro
23

Możesz to również zrobić, aby uczynić go bardziej dynamicznym.

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

Wtedy powtórzenie ng będzie wyglądać tak

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

Ten filtr będzie oczywiście używany tylko do filtrowania według polaryzacji

Llewellyn Collins
źródło
5

Mamy kolekcję, jak poniżej:


wprowadź opis obrazu tutaj

Składnia:

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

Przykład:

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

-LUB-

Składnia:

ng-bind="(input | filter)"

Przykład:

ng-bind="(Collectionstatus | filter:{Value:dt.Status})[0].KeyName"
Rahul Modi
źródło
4

Możesz tego spróbować. pracuje dla mnie „name” jest własnością w arr.

repeat="item in (tagWordOptions | filter:{ name: $select.search } ) track by $index
Satish Singh
źródło