So filtern Sie nach Objekteigenschaften in angleJS

139

Ich versuche, in AngularJS einen benutzerdefinierten Filter zu erstellen, der eine Liste von Objekten nach den Werten einer bestimmten Eigenschaft filtert. In diesem Fall möchte ich nach der Eigenschaft "Polarität" filtern (mögliche Werte von "Positiv", "Neutral", "Negativ").

Hier ist mein Arbeitscode ohne Filter:

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>

Hier ist das Array "$ scope.tweets" im JSON-Format:

{{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"}}

Der beste Filter, den ich finden konnte, ist wie folgt:

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

Diese Methode gibt ein leeres Array zurück. Aus der Anweisung "console.log (Polarität)" wird nichts gedruckt. Es scheint, als würde ich nicht die richtigen Parameter einfügen, um auf die Objekteigenschaft "Polarität" zuzugreifen.

Irgendwelche Ideen? Ihre Antwort wird sehr geschätzt.

sh3nan1gans
quelle
3
Schöne Frage, aber Code könnte reduziert werden, ein großer Teil davon ist für die Frage nicht relevant.
Setec

Antworten:

218

Sie müssen lediglich den filterFilter verwenden (siehe Dokumentation ):

<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

Schwarzes Loch
quelle
1
Gibt es eine Möglichkeit, die Elementliste zu filtern, indem ein benutzerdefinierter Filter an ein ng-click-Ereignis außerhalb der ng-repeat-Anweisung übergeben wird? In diesem Fall möchte ich drei "Polaritäts" -Schaltflächen über den Ergebnissen platzieren, die basierend auf der Bewertung gefiltert werden.
sh3nan1gans
2
Ich bin mir nicht sicher zu verstehen. Wenn Sie die zu filternde Polarität auswählen möchten, können Sie anstelle eines einfachen Textes eine Bereichsvariable übergeben: filter:{polarity:polarityToFilter}Diese $scope.polarityToFilterwird durch Klicken auf eine der drei Schaltflächen ausgefüllt. Versuchen Sie das zu tun?
Blackhole
Das scheint zu funktionieren. Meine App muss jedoch auch in der Lage sein, einzelne Listenelemente zu löschen.
sh3nan1gans
Das Problem beim Filtern besteht darin, dass jedes Mal, wenn ein Filter angewendet wird, ein neues Array erstellt wird, wodurch die Verbindung zwischen einem gefilterten Element und seinem ursprünglichen Index im ungefilterten Array unterbrochen wird. Gibt es eine Möglichkeit, die Krawatte aufrechtzuerhalten, oder ist ng-hide meine einzige Option? Hier ist ein Tutorial für eine Alternative zum Filtern mit ng-hide: bennadel.com/blog/…
sh3nan1gans
ngRepeat macht eine $indexEigenschaft des lokalen Bereichs verfügbar , die Sie auch verwenden können.
Blackhole
27

Die Dokumentation enthält die vollständige Antwort. Wie auch immer, so wird es gemacht:

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

filtert nur ageim dataArray und trueist für die genaue Übereinstimmung.

Zur Tiefenfilterung

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

Das $ist eine spezielle Eigenschaft für Tiefenfilter und das trueist für die exakte Übereinstimmung wie oben.

Abel Terefe
quelle
Einfach und sauber.
Scaryguy
Ist dieser Filter eingebaut oder muss er sowohl in Angular als auch in AngularJS geschrieben werden?
P Satish Patro
23

Sie können dies auch tun, um es dynamischer zu gestalten.

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

Dann wird Ihre ng-Wiederholung so aussehen

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

Dieser Filter wird natürlich nur zum Filtern nach Polarität verwendet

Llewellyn Collins
quelle
5

Wir haben Sammlung wie folgt:


Geben Sie hier die Bildbeschreibung ein

Syntax:

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

Beispiel:

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

-ODER-

Syntax:

ng-bind="(input | filter)"

Beispiel:

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

Sie können dies versuchen. seine Arbeit für mich 'Name' ist eine Eigenschaft in arr.

repeat="item in (tagWordOptions | filter:{ name: $select.search } ) track by $index
Satish Singh
quelle