如何在angularJS中按对象属性进行过滤

141

我正在尝试在AngularJS中创建一个自定义过滤器,该过滤器将按特定属性的值对对象列表进行过滤。在这种情况下,我想通过“极性”属性(可能的值为“积极”,“中性”,“消极”)来进行过滤。

这是没有过滤器的工作代码:

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>

这是 "$scope.tweets" 数组的 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"}}

我能想到的最好的过滤器如下:

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

这个方法返回一个空数组。而且从"console.log(polarity)"语句没有输出任何内容。看起来我没有插入正确的参数来访问"polarity"对象属性。

有什么想法吗?非常感谢您的回复。


3
好问题,但是代码可以精简,其中很大一部分与问题无关。 - setec
5个回答

219
你只需使用filter过滤器(请参见文档):
<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
有没有一种方法可以通过将自定义过滤器传递给ng-click事件来在ng-repeat语句之外过滤项目列表? 在这种情况下,我想在结果上方放置三个“极性”按钮,根据评分进行过滤。 - sh3nan1gans
2
我不确定是否理解。如果您想选择极性进行过滤,可以传递作用域变量而不是纯文本:filter:{polarity:polarityToFilter}其中$scope.polarityToFilter由单击三个按钮之一填充。这是您要做的吗? - Blackhole
那似乎可以行得通。然而,我的应用程序还需要能够删除单个列表项。 - sh3nan1gans
过滤的问题在于每次应用过滤器时都会创建一个新数组,这会打破过滤项与其在未过滤数组中的原始索引之间的联系。有没有一种方法可以保持联系,或者ng-hide是我的唯一选择?这里有一个使用ng-hide替代过滤器的教程:http://www.bennadel.com/blog/2487-Filter-vs-ngHide-With-ngRepeat-In-AngularJS.htm - sh3nan1gans
ngRepeat 在本地作用域上公开了一个 $index 属性,您也可以使用它。 - Blackhole
显示剩余3条评论

27

文档中有完整的答案。无论如何,以下是操作步骤:

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

将仅在data数组中过滤age,并且true表示精确匹配。

要进行深度过滤,

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

$是用于深度过滤的特殊属性,true表示进行精确匹配,如上所示。


简单而清晰。 - scaryguy
这个过滤器是内置的还是需要在Angular和AngularJS中编写? - Satish Patro

23

您还可以这样做,使它更加动态。

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

那么你的ng-repeat将会是这样的

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

这个过滤器当然只会被用来按极性进行过滤


5
以下是我们的集合:


enter image description here

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

例子:

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

-OR-

Syntax:

ng-bind="(input | filter)"

例子:


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

4
你可以尝试这样做。对我来说有效的'name'是arr中的一个属性。
repeat="item in (tagWordOptions | filter:{ name: $select.search } ) track by $index

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接