In Angular, ho bisogno di cercare oggetti in un array


114

In Angular, ho nell'ambito di un oggetto che restituisce molti oggetti. Ognuno ha un ID (questo è memorizzato in un file flat quindi nessun DB, e sembra che non sia in grado di utilizzarlo ng-resource)

Nel mio controller:

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

A mio avviso ho ulteriori informazioni sul pesce nascoste di default con ng-showmore, ma quando faccio clic sulla semplice scheda mostra di più, vorrei chiamare la funzione showdetails(fish.fish_id). La mia funzione sarebbe simile a:

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

Ora nella vista compaiono maggiori dettagli. Tuttavia, dopo aver cercato nella documentazione, non riesco a capire come cercare quell'array fish.

Quindi come interrogare l'array? E in console come chiamo il debugger in modo da avere l' $scopeoggetto con cui giocare?

Risposte:


95

So se questo può aiutarti un po '.

Ecco qualcosa che ho provato a simulare per te.

Controlla il jsFiddle;)

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

Creato un filtro che puoi utilizzare anche in "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;
  }
});

Utilizzo nel controller:

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 ci sono domande, fammelo sapere.


Dato che sono nuovo in angular e javascript, non ho capito il significato di "+" nell'istruzione "if (+ input [i] .id == + id) {", puoi condividere i tuoi pensieri.
Harshavardhan

Soluzione perfetta !!
Anil Kumar Ram

1
Penso che "+ input [i] .id == + id" ti assicuri di confrontare i numeri. Quindi puoi passare 1 o "1" al $ filter e si comporterebbe esattamente allo stesso modo. Sto utilizzando ID alfanumerici, quindi l'ho cambiato in "input [i] .id === id"
Axel Zehden

211

Puoi utilizzare il servizio $ filter esistente. Ho aggiornato il violino sopra 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 documentazione Angular è qui http://docs.angularjs.org/api/ng.filter:filter


2
molto utile - Man mano che imparo angolare, mi sto rendendo conto che devo smettere di pensare alle funzioni jQuery prima (stavo cercando di ottenere $ .grep per farlo) - piuttosto usare questo servizio $ filter era proprio quello di cui avevo bisogno!
Bobby

2
Risposta migliore in quanto non implica la scrittura di filtri personalizzati.
stevenw00

Potresti aggiungere dettagli cosa $scope.selectedè / contiene. Facendo un rapido ricerca sulla selezionato ho trovato ng-selected/ ngSelected: If the expression is truthy, then special attribute "selected" will be set on the element . È lo stesso? Nel tuo esempio cosa fa? Grazie
surfmuggle

1
Eccezionale !. Lo rende semplice. Grazie
Bharath

2
Non dimenticare di aggiungere il servizio $ filter al tuo controller. cioè: app.controller ('mainController', ['$ filter', function ($ filter) {// $ filter può ora essere usato.}]);
Lucas Reppe Welander

22

Per aggiungere alla risposta di @ migontech e anche al suo indirizzo il suo commento che potresti "probabilmente renderlo più generico", ecco un modo per farlo. Di seguito ti consentirà di cercare per qualsiasi proprietà:

.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 chiamata al filtro diventerebbe quindi:

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

Nota, ho rimosso l'operatore unario (+) per consentire corrispondenze basate su stringa ...


considerando che la documentazione afferma che questo è l'unico caso d'uso per ng-init, direi che questo è sicuramente il modo angolare per farlo.
bluehallu

Esempio molto facile da capire e molto utile
rainabba

13

Potrebbe sembrare una soluzione sporca e facile

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

5
Perché questa è una soluzione sporca ?
Trialcoder

5
la mia ipotesi sarebbe perché potrebbero esserci, tipo, un miliardo di record di pesce e li stiamo semplicemente scorrendo uno per uno
RedactedProfile

6
Ci sarebbero ancora più dischi in altre lingue. Voglio dire, ci sono molti pesci in C ++. (Oh zitto .. andrò a votare me stesso .. !!)
Mike Gledhill


7

Le tue soluzioni sono corrette ma non necessarie complicate. È possibile utilizzare la funzione di filtro javascript pura . Questo è il tuo modello:

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

E questa è la tua funzione:

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

Puoi anche usare l'espressione:

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

Ulteriori informazioni su questa funzione: LINK


4

Ho visto questo thread ma volevo cercare ID che non corrispondevano alla mia ricerca. Codice per farlo:

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

Questo ha funzionato per me. Semplice, fluido, facile da testare. Grazie!
Kalpesh Panchal
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.