Como filtrar por propriedade do objeto em angularJS

139

Estou tentando criar um filtro personalizado no AngularJS que filtrará uma lista de objetos pelos valores de uma propriedade específica. Nesse caso, quero filtrar pela propriedade "polaridade" (valores possíveis de "Positivo", "Neutro", "Negativo").

Aqui está o meu código de trabalho sem o filtro:

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>

Aqui está a matriz "$ scope.tweets" no formato 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"}}

O melhor filtro que eu poderia criar da seguinte maneira:

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

Este método retorna uma matriz vazia. E nada é impresso a partir da declaração "console.log (polaridade)". Parece que não estou inserindo os parâmetros corretos para acessar a propriedade do objeto "polaridade".

Alguma ideia? Sua resposta é muito apreciada.

sh3nan1gans
fonte
3
Boa pergunta, mas o código pode ser reduzido, grande parte dele não é relevante para a questão.
setec

Respostas:

218

Você simplesmente precisa usar o filterfiltro (consulte a documentação ):

<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

Blackhole
fonte
1
Existe uma maneira de filtrar a lista de itens passando um filtro personalizado para um evento ng-click fora da instrução ng-repeat? Nesse caso, quero colocar três botões de "polaridade" acima dos resultados que filtram com base na classificação.
Sh3nan1gans
2
Não tenho certeza de entender. Se você deseja escolher a polaridade a ser filtrada, pode passar uma variável de escopo em vez de um texto simples: filter:{polarity:polarityToFilter}onde $scope.polarityToFilteré preenchido por um clique em um dos três botões. É isso que você está tentando fazer?
Blackhole
Parece que poderia funcionar. No entanto, meu aplicativo também precisa excluir itens de lista individuais.
Sh3nan1gans
O problema com a filtragem é que uma nova matriz é criada toda vez que um filtro é aplicado, o que rompe o vínculo entre um item filtrado e seu índice original na matriz não filtrada. Existe uma maneira de manter o empate ou é ng-hide minha única opção? Aqui está um tutorial para uma alternativa à filtragem usando ng-hide: bennadel.com/blog/…
sh3nan1gans
O ngRepeat expõe uma $indexpropriedade no escopo local que você também pode usar.
Blackhole
27

A documentação tem a resposta completa. De qualquer forma, é assim que é feito:

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

filtrará apenas agena datamatriz e truecorresponde à correspondência exata.

Para filtragem profunda,

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

A $é uma propriedade especial para filtro de fundo e o trueé para correspondência exata como acima.

Abel Terefe
fonte
Simples e limpo.
scaryguy
Esse filtro está embutido ou precisa ser gravado no Angular & AngularJS?
P Satish Patro
23

Você também pode fazer isso para torná-lo mais dinâmico.

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

Então você ng-repeat ficará assim

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

É claro que este filtro será usado apenas para filtrar por polaridade

Llewellyn Collins
fonte
5

Temos coleção como abaixo:


insira a descrição da imagem aqui

Sintaxe:

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

Exemplo:

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

-OU-

Sintaxe:

ng-bind="(input | filter)"

Exemplo:

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

Você pode tentar isso. seu trabalho para mim 'nome' é uma propriedade em arr.

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