No Angular, preciso pesquisar objetos em uma matriz


114

No Angular, tenho no escopo um objeto que retorna muitos objetos. Cada um tem um ID (armazenado em um arquivo simples, sem banco de dados e não consigo utilizá-lo ng-resource)

No meu controlador:

$scope.fish = [
    {category:'freshwater', id:'1', name: 'trout', more:'false'},
    {category:'freshwater', id:'2', name:'bass', more:'false'}
];

Na minha opinião, tenho informações adicionais sobre os peixes ocultos por padrão com o ng-showmore, mas quando clico na guia simples mostrar mais, gostaria de chamar a função showdetails(fish.fish_id). Minha função seria algo como:

$scope.showdetails = function(fish_id) {  
    var fish = $scope.fish.get({id: fish_id});
    fish.more = true;
}

Agora, na visualização, mais detalhes aparecem. No entanto, depois de pesquisar a documentação, não consigo descobrir como pesquisar esse fisharray.

Então, como faço para consultar a matriz? E no console como eu chamo o debugger para que eu tenha o $scopeobjeto para brincar?

Respostas:


95

Eu sei se isso pode te ajudar um pouco.

Aqui está algo que tentei simular para você.

Verifique o jsFiddle;)

http://jsfiddle.net/migontech/gbW8Z/5/

Criou um filtro que você também pode usar em 'ng-repeat'

app.filter('getById', function() {
  return function(input, id) {
    var i=0, len=input.length;
    for (; i<len; i++) {
      if (+input[i].id == +id) {
        return input[i];
      }
    }
    return null;
  }
});

Uso no controlador:

app.controller('SomeController', ['$scope', '$filter', function($scope, $filter) {
     $scope.fish = [{category:'freshwater', id:'1', name: 'trout', more:'false'},  {category:'freshwater', id:'2', name:'bass', more:'false'}]

     $scope.showdetails = function(fish_id){
         var found = $filter('getById')($scope.fish, fish_id);
         console.log(found);
         $scope.selected = JSON.stringify(found);
     }
}]);

Se houver alguma dúvida, é só me avisar.


Como sou novo no angular e javascript, não estou entendendo o significado de '+' na declaração "if (+ input [i] .id == + id) {", por favor, compartilhe suas ideias.
Harshavardhan

Solução perfeita !!
Anil Kumar Ram,

1
Acho que o "+ input [i] .id == + id" garante que você está comparando os números. Assim, você pode passar 1 ou '1' para o filtro $ e ele se comportará exatamente da mesma maneira. Estou usando IDs alfanuméricos, então mudei para "input [i] .id === id"
Axel Zehden

211

Você pode usar o serviço $ filter existente. Eu atualizei o violino acima http://jsfiddle.net/gbW8Z/12/

 $scope.showdetails = function(fish_id) {
     var found = $filter('filter')($scope.fish, {id: fish_id}, true);
     if (found.length) {
         $scope.selected = JSON.stringify(found[0]);
     } else {
         $scope.selected = 'Not found';
     }
 }

A documentação angular está aqui http://docs.angularjs.org/api/ng.filter:filter


2
muito útil - À medida que aprendo angular, estou percebendo que preciso parar de pensar nas funções jQuery primeiro (estava tentando fazer com que $ .grep fizesse isso) - em vez disso, usar esse serviço $ filter era exatamente o que eu precisava!
Bobby

2
Melhor resposta, pois não envolve escrever seus próprios filtros.
stevenw00

Você poderia adicionar detalhes o que $scope.selectedé / contém. Fazendo uma rápida pesquisa-on selecionado i encontrado ng-selected/ ngSelected: If the expression is truthy, then special attribute "selected" will be set on the element . Isso é o mesmo? No seu exemplo, o que isso faz? Obrigado
surfmuggle

1
Impressionante !. Torna mais simples. Obrigado
Bharath

2
Não se esqueça de adicionar o serviço $ filter ao seu controlador. ou seja: app.controller ('mainController', ['$ filter', function ($ filter) {// $ filter agora pode ser usado.}]);
Lucas Reppe Welander

22

Para adicionar à resposta de @migontech e também ao endereço dele, o comentário de que você poderia "provavelmente torná-lo mais genérico", aqui está uma maneira de fazer isso. A seguir, você poderá pesquisar por qualquer propriedade:

.filter('getByProperty', function() {
    return function(propertyName, propertyValue, collection) {
        var i=0, len=collection.length;
        for (; i<len; i++) {
            if (collection[i][propertyName] == +propertyValue) {
                return collection[i];
            }
        }
        return null;
    }
});

A chamada para filtrar se tornaria:

var found = $filter('getByProperty')('id', fish_id, $scope.fish);

Observe, removi o operador unário (+) para permitir correspondências baseadas em string ...


considerando que a documentação afirma que este é o único caso de uso para ng-init, eu diria que esta é definitivamente a maneira Angular de fazer isso.
bluehallu de

Exemplo muito fácil de entender e muito útil
rainabba

13

Uma solução suja e fácil pode parecer

$scope.showdetails = function(fish_id) {
    angular.forEach($scope.fish, function(fish, key) {
        fish.more = fish.id == fish_id;
    });
};

5
Por que essa é uma solução suja ?
Trialcoder

5
meu palpite seria porque pode haver, tipo, um bilhão de registros de peixes e estamos apenas repetindo-os um por um
RedactedProfile

6
Haveria ainda mais registros em outros idiomas. Quer dizer, há muitos peixes no C ++. (Oh, cale a boca .. Vou votar em mim mesmo .. !!)
Mike Gledhill


7

Suas soluções são corretas, mas desnecessariamente complicadas. Você pode usar a função de filtro de javascript puro . Este é o seu modelo:

     $scope.fishes = [{category:'freshwater', id:'1', name: 'trout', more:'false'},  {category:'freshwater', id:'2', name:'bass', more:'false'}];

E esta é a sua função:

     $scope.showdetails = function(fish_id){
         var found = $scope.fishes.filter({id : fish_id});
         return found;
     };

Você também pode usar a expressão:

     $scope.showdetails = function(fish_id){
         var found = $scope.fishes.filter(function(fish){ return fish.id === fish_id });
         return found;
     };

Mais sobre esta função: LINK


4

Vi este tópico, mas queria pesquisar por IDs que não correspondem à minha pesquisa. Código para fazer isso:

found = $filter('filter')($scope.fish, {id: '!fish_id'}, false);

Isso funcionou para mim. Simples, elegante e fácil de testar. Obrigado!
Kalpesh Panchal
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.