Как фильтровать по свойству объекта в 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.