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?

cuillère à soupe
la source

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.

migontech
la source
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

Adrian Gunawan
la source
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 ...

Herringtown
la source
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;
    });
};
Arun P Johny
la source
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

Michał Jarzyna
la source
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);
Ogglas
la source
Cela a fonctionné pour moi. Simple, élégant, facile à tester. Merci!
Kalpesh Panchal