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

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


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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.