Filtrando por várias propriedades de modelo específico em AngularJS (em relação OR)

Dê uma olhada no exemplo aqui: http://docs.angularjs.org/api/ng.filter:filter

Você pode pesquisar por qualquer uma das propriedades do telefone usando e pode pesquisar apenas pelo nome usando , e os resultados são filtrados adequadamente por nome (digitar um número de telefone não retorna nenhum resultado, como esperado).

Digamos que eu tenha um modelo com uma propriedade “name”, uma propriedade “phone” e uma propriedade “secret”, como eu faria filtragem pelas propriedades “name” e “phone” e não pela propriedade “secret”? ? Então, em essência, o usuário poderia digitar um nome ou número de telefone e o ng-repeat filtraria corretamente, mas mesmo que o usuário digitasse um valor que igualasse parte de um valor “secreto”, ele não retornaria nada.

Obrigado.

   

Aqui é o plunker

Novo plunker com código de limpeza e onde os itens da lista de consulta e de pesquisa não diferenciam maiúsculas de minúsculas

A ideia principal é criar uma function de filtro para atingir esse objective.

Do documento oficial

function: Uma function de predicado pode ser usada para gravar filtros arbitrários. A function é chamada para cada elemento da matriz. O resultado final é uma matriz desses elementos para os quais o predicado retornou true.

   

 $scope.search = function(item) { if (!$scope.query || (item.brand.toLowerCase().indexOf($scope.query) != -1) || (item.model.toLowerCase().indexOf($scope.query.toLowerCase()) != -1) ){ return true; } return false; }; 

Atualizar

Algumas pessoas podem ter uma preocupação com o desempenho no mundo real, o que é correto.

No mundo real, provavelmente faríamos esse tipo de filtro do controlador.

Aqui está o post de detalhes mostrando como fazer isso.

Em resumo, adicionamos ng-change à input para monitorar novas alterações de pesquisa

e, em seguida, acione a function de filtro.

Você pode passar um object como o parâmetro para sua expressão de filtro, conforme descrito na referência da API . Este object pode aplicar seletivamente as propriedades que você está interessado, assim:

     

Aqui está um Plunker

Atenção: este exemplo funciona muito bem com o AngularJS 1.1.5, mas nem sempre é tão bom no 1.0.7. Neste exemplo, o 1.0.7 inicializará com tudo filtrado e, em seguida, funcionará quando você começar a usar as inputs. Ele se comporta como se as inputs tivessem valores não correspondentes, apesar de começarem em branco. Se você quiser ficar em versões estáveis, vá em frente e tente fazer isso para a sua situação, mas alguns cenários podem querer usar a solução do @ maxisam até que o 1.2.0 seja lançado.

Eu me inspirei na resposta do @ maxisam e criei minha própria function de sorting e eu gostaria de compartilhá-la (porque estou entediado).

Situação Eu quero filtrar através de uma matriz de carros. As propriedades selecionadas para filtrar são nome, ano, preço e km. O preço da propriedade e km são números (daí o uso de .toString ). Eu também quero controlar letras maiúsculas (daí .toLowerCase ). Também quero ser capaz de dividir a minha consulta de filtro em palavras diferentes (por exemplo, dado o filtro Acura 2006, encontra correspondências 2006 com o ano e Acura com o nome).

Função eu passo para filtrar

  var attrs = [car.name.toLowerCase(), car.year, car.price.toString(), car.km.toString()], filters = $scope.tableOpts.filter.toLowerCase().split(' '), isStringInArray = function (string, array){ for (var j=0;j 

Se você está aberto para usar bibliotecas de terceiros, os “Filtros Angulares” com uma boa coleção de filtros podem ser úteis:

https://github.com/a8m/angular-filter#filterby

 collection | filterBy: [prop, nested.prop, etc..]: search 

Espero que esta resposta ajude, Multiple Value Filter

E exemplo de trabalho neste violino

 arrayOfObjectswithKeys | filterMultiple:{key1:['value1','value2','value3',...etc],key2:'value4',key3:[value5,value6,...etc]} 

Há um monte de boas soluções aqui, mas eu sugiro ir a outra rota com isso. Se pesquisar é a coisa mais importante e a propriedade ‘secreta’ não é usada na exibição; Minha abordagem para isso seria usar o filtro angular integrado com todos os seus benefícios e simplesmente mapear o modelo para uma nova matriz de objects.

Exemplo da pergunta:

 $scope.people = members.map(function(member) { return { name: member.name, phone: member.phone }}); 

Agora, em html, simplesmente use o filtro regular para pesquisar essas duas propriedades.

 

http://plnkr.co/edit/A2IG03FLYnEYMpZ5RxEm?p=preview

Aqui está uma pesquisa sensível a maiúsculas e minúsculas que também separa sua pesquisa em palavras para pesquisar em cada modelo também. Somente quando encontrar um espaço, ele tentará dividir a consulta em uma matriz e pesquisar cada palavra.

Ele retorna true se cada palavra estiver pelo menos em um dos modelos.

 $scope.songSearch = function (row) { var query = angular.lowercase($scope.query); if (query.indexOf(" ") > 0) { query_array = query.split(" "); search_result = false; for (x in query_array) { query = query_array[x]; if (angular.lowercase(row.model1).indexOf(query || '') !== -1 || angular.lowercase(row.model2).indexOf(query || '') !== -1 || angular.lowercase(row.model3).indexOf(query || '') !== -1){ search_result = true; } else { search_result = false; break; } } return search_result; } else { return (angular.lowercase(row.model1).indexOf(query || '') !== -1 || angular.lowercase(row.model2).indexOf(query || '') !== -1 || angular.lowercase(row.model3).indexOf(query || '') !== -1); } }; 

Abordagem bastante simples usando filterBy em angularJs

Para trabalhar plnkr siga este link

http://plnkr.co/edit/US6xE4h0gD5CEYV0aMDf?p=preview

Isso usou especialmente uma única propriedade para pesquisar em várias colunas, mas não em todas.

 < !DOCTYPE html>          
{{row.col1}} {{row.col2}} {{row.col3}}

This will show filter from two columns only(col1 and col2) . Not from all. Whatever columns you add into filter array they will be searched. all columns will be used by default if you use filter: vm.searchText

controlador

 // Code goes here (function(){ var myApp = angular.module('myApp',['angular.filter']); myApp.controller('myCtrl', function($scope){ var vm= this; vm.x = 20; vm.tableData = [ { col1: 'Ashok', col2: 'Tewatia', col3: '12' },{ col1: 'Babita', col2: 'Malik', col3: '34' },{ col1: 'Dinesh', col2: 'Tewatia', col3: '56' },{ col1: 'Sabita', col2: 'Malik', col3: '78' } ]; }) })(); 

Eu gosto de manter é simples quando possível. Eu precisava agrupar por Internacional, filtrar todas as colunas, exibir a contagem para cada grupo e ocultar o grupo se não existissem itens.

Além disso, eu não queria adicionar um filtro personalizado apenas para algo simples como este.

   

USA ({{fusa.length}})

{{$index + 1}}

International ({{fint.length}})

{{$index + 1}}

O filtro pode ser um object JavaScript com campos e você pode ter expressão como:

 ng-repeat= 'item in list | filter :{property:value}' 

Aqui está uma solução simples para aqueles que querem um filtro rápido contra um object:

  

O filtro de matriz permite imitar o object que você está tentando filtrar. No caso acima, as seguintes classs funcionariam bem:

 var card = function(name, type) { var _name = name; var _type = type; return { Name: _name, Type: _type }; }; 

E onde o baralho pode parecer:

 var deck = function() { var _cards = [new card('Jack', 'Face'), new card('7', 'Numeral')]; return { Cards: _cards }; }; 

E se você quiser filtrar várias propriedades do object, separe os nomes dos campos por vírgula:

  

EDIT: Aqui está um plnkr de trabalho que fornece um exemplo de filtros de propriedade única e múltipla:

http://embed.plnkr.co/i0wCx6l1WPYljk57SXzV/

Eu posso estar muito atrasado, mas foi o que acabei fazendo. Eu fiz um filtro muito geral.

 angular.module('app.filters').filter('fieldFilter', function() { return function(input, clause, fields) { var out = []; if (clause && clause.query && clause.query.length > 0) { clause.query = String(clause.query).toLowerCase(); angular.forEach(input, function(cp) { for (var i = 0; i < fields.length; i++) { var haystack = String(cp[fields[i]]).toLowerCase(); if (haystack.indexOf(clause.query) > -1) { out.push(cp); break; } } }) } else { angular.forEach(input, function(cp) { out.push(cp); }) } return out; } }) 

Então use-o assim

  

Sua checkbox de pesquisa é como

  

onde name e device_id são propriedades em dvs