W Angular muszę wyszukiwać obiekty w tablicy

114

W Angular mam w zakresie obiekt, który zwraca wiele obiektów. Każdy ma identyfikator (jest przechowywany w płaskim pliku, więc nie ma bazy danych i wydaje się, że nie jestem w stanie użytkownika ng-resource)

W moim kontrolerze:

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

Moim zdaniem mam dodatkowe informacje o rybach ukrytych domyślnie im ng-showwięcej, ale kiedy kliknę prostą zakładkę pokaż więcej, chciałbym wywołać funkcję showdetails(fish.fish_id). Moja funkcja wyglądałaby tak:

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

Teraz w widoku pojawia się więcej szczegółów. Jednak po przeszukaniu dokumentacji nie mogę dowiedzieć się, jak przeszukać tę fishtablicę.

Jak więc zapytać o tablicę? A jak w konsoli wywołać debugger, żeby mieć $scopeobiekt do zabawy?

łyżeczka
źródło

Odpowiedzi:

95

Wiem, czy to ci trochę pomoże.

Oto coś, co próbowałem dla ciebie zasymulować.

Sprawdź jsFiddle;)

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

Utworzono filtr, którego możesz również użyć w „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;
  }
});

Wykorzystanie w kontrolerze:

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

Jeśli są jakieś pytania, daj mi znać.

migontech
źródło
Ponieważ jestem nowy w angular i javascript, nie rozumiem znaczenia „+” w wyrażeniu „if (+ input [i] .id == + id) {”, czy możesz podzielić się swoimi przemyśleniami.
Harshavardhan
Idealne rozwiązanie !!
Anil Kumar Ram
1
Myślę, że „+ input [i] .id == + id” zapewnia porównywanie liczb. Możesz więc przekazać $ filter 1 lub '1' i zachowa się dokładnie w ten sam sposób. Używam alfanumerycznych identyfikatorów, więc zmieniłem je na „input [i] .id === id”
Axel Zehden,
211

Możesz użyć istniejącej usługi $ filter. Zaktualizowałem skrzypce powyżej 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';
     }
 }

Dokumentacja Angular jest tutaj http://docs.angularjs.org/api/ng.filter:filter

Adrian Gunawan
źródło
2
bardzo pomocny - Kiedy uczę się kątowego, zdaję sobie sprawę, że muszę najpierw przestać myśleć o funkcjach jQuery (próbowałem uzyskać $ .grep, aby to zrobić) - raczej użycie tej usługi $ filter było tym, czego potrzebowałem!
Bobby
2
Lepsza odpowiedź, ponieważ nie wymaga pisania własnych filtrów.
stevenw00
Czy możesz dodać szczegóły, co $scope.selectedjest / zawiera. Robi Szybkiego Wyszukiwania na wybrany znalazłem ng-selected/ ngSelected: If the expression is truthy, then special attribute "selected" will be set on the element . Czy to jest to samo? Na twoim przykładzie, co to robi? Dzięki
surfmuggle
1
Niesamowite !. Ułatwia to. Dzięki
Bharath
2
Nie zapomnij dodać usługi $ filter do swojego kontrolera. ie: app.controller ('mainController', ['$ filter', function ($ filter) {// $ filter.}]);
Lucas Reppe Welander
22

Aby dodać do odpowiedzi @ migontech, a także jego adres, komentarz, że „prawdopodobnie mógłbyś uczynić ją bardziej ogólną”, oto sposób, aby to zrobić. Poniższe umożliwiają wyszukiwanie według dowolnej nieruchomości:

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

Wezwanie do filtrowania wyglądałoby wówczas następująco:

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

Uwaga, usunąłem operator jednoargumentowy (+), aby umożliwić dopasowania oparte na ciągach znaków ...

herringtown
źródło
biorąc pod uwagę, że dokumentacja stwierdza, że ​​jest to jedyny przypadek użycia ng-init, powiedziałbym, że jest to zdecydowanie sposób Angular.
bluehallu,
Bardzo łatwy do zrozumienia przykład i bardzo pomocny
rainabba
13

Może wyglądać brudne i łatwe rozwiązanie

$scope.showdetails = function(fish_id) {
    angular.forEach($scope.fish, function(fish, key) {
        fish.more = fish.id == fish_id;
    });
};
Arun P Johny
źródło
5
Dlaczego to jest brudne rozwiązanie?
Trialcoder
5
przypuszczam, że może być miliard rekordów ryb i po prostu przeglądamy je jeden po drugim
RedactedProfile
6
W innych językach byłoby jeszcze więcej nagrań. Mam na myśli, że w C ++ jest mnóstwo ryb. (Och, zamknij się… Pójdę i zagłosuję za siebie… !!)
Mike Gledhill,
7

Twoje rozwiązania są poprawne, ale niepotrzebnie skomplikowane. Możesz użyć czystej funkcji filtru javascript . To jest twój model:

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

A to twoja funkcja:

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

Możesz też użyć wyrażenia:

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

Więcej o tej funkcji: LINK

Michał Jarzyna
źródło
4

Widziałem ten wątek, ale chciałem wyszukać identyfikatory, które nie pasują do mojego wyszukiwania. Kod do tego:

found = $filter('filter')($scope.fish, {id: '!fish_id'}, false);
Ogglas
źródło
To zadziałało dla mnie. Prosty, zgrabny, łatwy do przetestowania. Dzięki!
Kalpesh Panchal