Dans Angular, j'ai besoin de rechercher des objets dans un tableau


114

Dans Angular, j'ai dans la portée un objet qui retourne beaucoup d'objets. Chacun a un identifiant (celui-ci est stocké dans un fichier plat donc pas de DB, et je ne semble pas pouvoir utiliser ng-resource)

Dans mon contrôleur:

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

À mon avis, j'ai des informations supplémentaires sur le poisson caché par défaut avec le ng-showplus, mais lorsque je clique sur l'onglet simple afficher plus, je voudrais appeler la fonction showdetails(fish.fish_id). Ma fonction ressemblerait à quelque chose comme:

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

Maintenant, dans la vue, plus de détails apparaissent. Cependant, après avoir parcouru la documentation, je ne peux pas comprendre comment rechercher ce fishtableau.

Alors, comment interroger le tableau? Et dans la console, comment appeler le débogueur pour avoir l' $scopeobjet avec lequel jouer?

Réponses:


95

Je sais si cela peut vous aider un peu.

Voici quelque chose que j'ai essayé de simuler pour vous.

Découvrez le jsFiddle;)

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

Création d'un filtre que vous pouvez également utiliser dans '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;
  }
});

Utilisation dans le contrôleur:

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

S'il y a des questions, faites-le moi savoir.


Comme je suis nouveau dans angular et javascript, je ne comprends pas la signification de '+' dans la déclaration "if (+ input [i] .id == + id) {", pouvez-vous s'il vous plaît partager vos pensées.
Harshavardhan

Solution parfaite !!
Anil Kumar Ram

1
Je pense que le "+ input [i] .id == + id" garantit que vous comparez des nombres. Vous pouvez donc passer 1 ou '1' au filtre $ et il se comporterait exactement de la même manière. J'utilise des identifiants alphanumériques, alors je l'ai changé en "input [i] .id === id"
Axel Zehden

211

Vous pouvez utiliser le service $ filter existant. J'ai mis à jour le violon ci-dessus 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 documentation angulaire est ici http://docs.angularjs.org/api/ng.filter:filter


2
très utile - Au fur et à mesure que j'apprends angular, je me rends compte que je dois d'abord arrêter de penser aux fonctions jQuery (j'essayais d'obtenir $ .grep pour le faire) - utiliser plutôt ce service $ filter était exactement ce dont j'avais besoin!
Bobby

2
Meilleure réponse car cela n'implique pas d'écrire vos propres filtres.
stevenw00

Pourriez-vous ajouter des détails sur ce qui $scope.selectedest / contient. Faire une recherche rapide sur sélectionné i trouvé ng-selected/ ngSelected: If the expression is truthy, then special attribute "selected" will be set on the element . Est-ce la même chose? Dans votre exemple, que fait-il? Merci
surfmuggle

1
Impressionnant !. Rend les choses simples. Merci
Bharath

2
N'oubliez pas d'ajouter le service $ filter à votre contrôleur. ie: app.controller ('mainController', ['$ filter', function ($ filter) {// $ filter peut maintenant être utilisé.}]);
Lucas Reppe Welander

22

Pour ajouter à la réponse de @ migontech et aussi à son adresse son commentaire que vous pourriez "probablement rendre plus générique", voici une façon de le faire. Ce qui suit vous permettra de rechercher par n'importe quelle propriété:

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

L'appel au filtrage deviendrait alors:

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

Remarque, j'ai supprimé l'opérateur unaire (+) pour permettre les correspondances basées sur des chaînes ...


considérant que la documentation indique que c'est le seul cas d'utilisation de ng-init, je dirais que c'est définitivement la manière angulaire de le faire.
bluehallu

Exemple très facile à comprendre et très utile
rainabba

13

Une solution sale et facile pourrait ressembler à

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

5
Pourquoi est-ce une sale solution?
Trialcoder

5
je suppose qu'il y a peut-être un milliard d'enregistrements de poissons et que nous les parcourons un par un
Profil

6
Il y aurait encore plus de disques dans d'autres langues. Je veux dire, il y a beaucoup de poisson dans le C ++. (Oh tais-toi ... je vais aller voter moi-même ... !!)
Mike Gledhill


7

Vos solutions sont correctes mais inutiles compliquées. Vous pouvez utiliser la fonction de filtre javascript pur . Voici votre modèle:

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

Et c'est votre fonction:

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

Vous pouvez également utiliser l'expression:

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

En savoir plus sur cette fonction: LINK


4

J'ai vu ce fil, mais je voulais rechercher des identifiants qui ne correspondent pas à ma recherche. Code pour faire cela:

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

Cela a fonctionné pour moi. Simple, élégant, facile à tester. Merci!
Kalpesh Panchal
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.