En Angular, necesito buscar objetos en una matriz

114

En Angular, tengo en alcance un objeto que devuelve muchos objetos. Cada uno tiene una identificación (esto se almacena en un archivo plano, por lo que no hay base de datos, y parece que no puedo usarlo ng-resource)

En mi controlador:

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

En mi opinión, tengo información adicional sobre los peces ocultos por defecto con ng-showmás, pero cuando hago clic en la pestaña simple mostrar más, me gustaría llamar a la función showdetails(fish.fish_id). Mi función se vería así:

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

Ahora en la vista se muestran más detalles. Sin embargo, después de buscar en la documentación, no puedo averiguar cómo buscar esa fishmatriz.

Entonces, ¿cómo consulto la matriz? Y en la consola, ¿cómo llamo al depurador para tener el $scopeobjeto con el que jugar?

tspore
fuente

Respuestas:

95

Sé si eso te puede ayudar un poco.

Aquí hay algo que intenté simular para ti.

Verifique el jsFiddle;)

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

Creó un filtro que también puede usar en '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 en 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);
     }
}]);

Si tiene alguna pregunta, hágamelo saber.

migontech
fuente
Como soy nuevo en angular y javascript, no entiendo el significado de '+' en la declaración "if (+ input [i] .id == + id) {", ¿puede compartir sus pensamientos?
Harshavardhan
Solución perfecta !!
Anil Kumar Ram
1
Creo que "+ input [i] .id == + id" asegura que estás comparando números. Entonces puede pasar 1 o '1' al filtro $ y se comportaría exactamente de la misma manera. Estoy usando ID alfanuméricos, así que lo cambié a "input [i] .id === id"
Axel Zehden
211

Puede utilizar el servicio de filtro $ existente. Actualicé el violín de arriba 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';
     }
 }

La documentación angular está aquí http://docs.angularjs.org/api/ng.filter:filter

Adrian Gunawan
fuente
2
muy útil: a medida que aprendo angular, me doy cuenta de que primero necesito dejar de pensar en las funciones jQuery (estaba tratando de obtener $ .grep para hacer esto), ¡en lugar de usar este servicio de $ filter era justo lo que necesitaba!
Bobby
2
Mejor respuesta, ya que no implica escribir sus propios filtros.
stevenw00
¿Podría agregar detalles de lo que $scope.selectedes / contiene? Haciendo una búsqueda rápida en el seleccionado he encontrado ng-selected/ ngSelected: If the expression is truthy, then special attribute "selected" will be set on the element . ¿Es esto lo mismo? En su ejemplo, ¿qué hace? Gracias
surfmuggle
1
Increíble !. Lo hace simple. Gracias
Bharath
2
No olvide agregar el servicio $ filter a su controlador. es decir: app.controller ('mainController', ['$ filter', function ($ filter) {// Ahora se puede usar $ filter.}]);
Lucas Reppe Welander
22

Para agregar a la respuesta de @ migontech y también a su dirección su comentario de que "probablemente podría hacerlo más genérico", aquí hay una manera de hacerlo. Lo siguiente le permitirá buscar por cualquier propiedad:

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

La llamada a filtrar se convertiría entonces en:

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

Tenga en cuenta que eliminé el operador unario (+) para permitir coincidencias basadas en cadenas ...

herringtown
fuente
considerando que la documentación indica que este es el único caso de uso de ng-init, diría que esta es definitivamente la forma angular de hacerlo.
bluehallu
Ejemplo muy fácil de entender y muy útil
rainabba
13

Una solución fácil y sucia podría parecer

$scope.showdetails = function(fish_id) {
    angular.forEach($scope.fish, function(fish, key) {
        fish.more = fish.id == fish_id;
    });
};
Arun P Johny
fuente
5
¿Por qué esta es una solución sucia ?
Trialcoder
5
mi suposición sería porque puede haber, como, mil millones de registros de peces y los estamos revisando uno por uno
RedactedProfile
6
Habría incluso más registros en otros idiomas. Quiero decir, hay muchos peces en C ++. (Oh, cállate ... ¡¡Iré y votaré en contra ... !!)
Mike Gledhill
7

Tus soluciones son correctas pero innecesariamente complicadas. Puede utilizar la función de filtro de JavaScript puro . Este es tu modelo:

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

Y esta es tu función:

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

También puede usar la expresión:

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

Más sobre esta función: LINK

Michał Jarzyna
fuente
4

Vi este hilo, pero quería buscar ID que no coincidieran con mi búsqueda. Código para hacer eso:

found = $filter('filter')($scope.fish, {id: '!fish_id'}, false);
Ogglas
fuente
Esto funcionó para mí. Simple, hábil, fácil de probar. ¡Gracias!
Kalpesh Panchal