Как фильтровать по свойству объекта в 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 (полярность)". Похоже, я не вставляю правильные параметры для доступа к свойству объекта «полярность».

Любые идеи? Ваш ответ очень признателен.

sh3nan1gans
источник
3
Хороший вопрос, но код можно сократить, большая его часть не имеет отношения к вопросу.
setec

Ответы:

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: bennadel.com/blog/…
sh3nan1gans
ngRepeat предоставляет $indexсвойство в локальной области видимости, которое вы также можете использовать.
Blackhole
27

В документации есть полный ответ. Во всяком случае, как это делается:

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

будет фильтровать только ageв dataмассиве и trueдля точного совпадения.

Для глубокой фильтрации,

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

Это $специальное свойство для глубокого фильтра и trueдля точного совпадения, как указано выше.

Абель Терефе
источник
Просто и чисто.
scaryguy
Этот фильтр встроен или должен быть написан как на Angular, так и на AngularJS?
P 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

У нас есть коллекция, как показано ниже:


введите описание изображения здесь

Синтаксис:

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

Пример:

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

-ИЛИ-

Синтаксис:

ng-bind="(input | filter)"

Пример:

ng-bind="(Collectionstatus | filter:{Value:dt.Status})[0].KeyName"
Рахул Моди
источник
4

Вы можете попробовать это. его рабочее для меня "имя" - собственность в обр.

repeat="item in (tagWordOptions | filter:{ name: $select.search } ) track by $index
Сатиш Сингх
источник