Angular'da, bir dizideki nesneleri aramam gerekiyor


114

Angular'da, çok sayıda nesne döndüren bir nesneye sahibim. Her birinin bir kimliği vardır (bu, düz bir dosyada saklanır, bu nedenle DB yok ve kullanıcı yapamıyorum gibi görünüyor ng-resource)

Denetleyicimde:

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

Benim görüşüme göre, varsayılan olarak ng-showdaha fazla olan balıklar hakkında ek bilgilerim var , ancak basit göster daha fazla sekmesini tıkladığımda, işlevi çağırmak istiyorum showdetails(fish.fish_id). İşlevim şuna benzer:

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

Şimdi görünümde daha fazla ayrıntı ortaya çıkıyor. Ancak dokümantasyonu araştırdıktan sonra bu fishdiziyi nasıl arayacağımı çözemiyorum.

Peki diziyi nasıl sorgulayabilirim? Ve konsolda $scope, oynamak için nesneye sahip olmak için hata ayıklayıcıyı nasıl çağırırım ?

Yanıtlar:


95

Bunun size biraz yardımcı olup olmayacağını biliyorum.

İşte sizin için simüle etmeye çalıştığım bir şey.

JsFiddle'a göz atın;)

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

'Ng-tekrarında' da kullanabileceğiniz bir filtre oluşturuldu

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

Denetleyicide kullanım:

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

Herhangi bir sorunuz varsa bana bildirin.


Angular ve javascript konusunda yeni olduğum için, "if (+ input [i] .id == + id) {" ifadesindeki '+' ifadesinin anlamını alamıyorum, lütfen düşüncelerinizi paylaşır mısınız?
Harshavardhan

Mükemmel çözüm !!
Anil Kumar Ram

1
Bence "+ input [i] .id == + id" sayıları karşılaştırmanızı sağlıyor. Yani $ filtresine 1 veya '1' geçebilirsiniz ve aynı şekilde davranır. Alfasayısal kimlikler kullanıyorum, bu yüzden onu "input [i] .id === id" olarak değiştirdim
Axel Zehden

211

Mevcut $ filtre hizmetini kullanabilirsiniz. Yukarıdaki keman'ı güncelledim 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';
     }
 }

Açısal belgeler burada http://docs.angularjs.org/api/ng.filter:filter


2
çok yardımcı oldu - Açısal öğrendikçe, önce jQuery işlevlerini düşünmeyi bırakmam gerektiğini anlıyorum (bunu yapmak için $ .grep almaya çalışıyordum) - bu $ filtre hizmetini kullanmak tam da ihtiyacım olan şeydi!
Bobby

2
Kendi filtrelerinizi yazmayı gerektirmediğinden daha iyi cevap.
stevenw00

Neyin $scope.selected/ neyin bulunduğunu detaylandırır mısınız Ben buldum seçilen bir hızlı arama yaparak ng-selected/ ngSelected: If the expression is truthy, then special attribute "selected" will be set on the element . Bu aynı mı? Örneğinizde ne işe yarar? Teşekkürler
surfmuggle

1
Harika!. Bunu basitleştirir. Teşekkürler
Bharath

2
Denetleyicinize $ filtre hizmetini eklemeyi unutmayın. yani: app.controller ('mainController', ['$ filter', function ($ filter) {// $ filtre artık kullanılabilir.}]);
Lucas Reppe Welander

22

@ Migontech'in cevabına ve aynı zamanda adresini "muhtemelen daha genel yapabileceğiniz" yorumunu eklemek için, işte bunu yapmanın bir yolu. Aşağıdakiler herhangi bir mülke göre arama yapmanıza izin verecektir:

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

Filtreleme çağrısı daha sonra şöyle olur:

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

Not, dize tabanlı eşleşmelere izin vermek için tekli (+) operatörünü kaldırdım ...


Dokümantasyonun bunun ng-init için tek kullanım durumu olduğunu belirttiğini düşünürsek, bunun kesinlikle bunu yapmanın Angular yolu olduğunu söyleyebilirim.
bluehallu


13

Kirli ve kolay bir çözüm şöyle görünebilir:

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

5
Bu neden kirli bir çözüm?
Trialcoder

5
Tahminime göre, bir milyar balık kaydı olabilir ve biz sadece tek tek gözden geçiriyoruz
RedactedProfile

6
Diğer dillerde daha da fazla kayıt olacaktır. Demek istediğim, C ++ 'da bol miktarda balık var. (Kapa çeneni .. Gidip kendime oy vereceğim .. !!)
Mike Gledhill


7

Çözümleriniz doğru ama gereksiz karmaşık. Saf javascript filtre işlevini kullanabilirsiniz . Bu senin modelin:

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

Ve bu senin işlevin:

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

Ayrıca ifade de kullanabilirsiniz:

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

Bu işlev hakkında daha fazla bilgi: LINK


4

Bu konuyu gördüm ama aramamla eşleşmeyen kimlikleri aramak istedim. Bunu yapmak için kod:

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

Bu benim için çalıştı. Basit, kaygan, test etmesi kolay. Teşekkürler!
Kalpesh Panchal
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.