AngularJs'de ng-tekrar ile nasıl filtreleme (anahtar, değer) yapılır?


113

Şunun gibi bir şey yapmaya çalışıyorum:

<div ng-controller="TestCtrl">
    <div ng-repeat="(k,v) in items | filter:hasSecurityId">
        {{k}} {{v.pos}}
    </div>
</div>

AngularJs Bölümü:

function TestCtrl($scope) 
{
    $scope.items = {
                     'A2F0C7':{'secId':'12345', 'pos':'a20'},
                     'C8B3D1':{'pos':'b10'}
                   };

    $scope.hasSecurityId = function(k,v)
    {
       return v.hasOwnProperty('secId');
    }
}

Ama bir şekilde bana tüm öğeleri gösteriyor. (Anahtar, değer) için nasıl filtreleme yapabilirim?


lütfen bazı örnek veri öğeleri sağlayın. Veya bize bir keman ver;)
Robin Drexler

Belgelere bu şekilde filtre oluşturmazsınız ve Robin'in dediği gibi bir örnek lütfen.
Yahya KACEM

Zaten tam bir örnek verdim ve filtreleri nasıl kullanacağımı biliyorum. Sadece "(anahtar, değer) ile filtre nasıl kullanılır" diye soruyorum.
Vural

index ve count bu kapsamda mevcut olmalıdır iirc
Shanimal

Yanıtlar:


131

Angular API'sinden açısal filtreler nesnelere değil yalnızca dizilere uygulanabilir -

"Dizideki öğelerin bir alt kümesini seçer ve onu yeni bir dizi olarak döndürür."

Burada iki seçeneğiniz var:
1) $scope.itemsbir diziye geçme veya -
2) ng-repeatöğeleri önceden filtreleme , örneğin:

<div ng-repeat="(k,v) in filterSecId(items)">
    {{k}} {{v.pos}}
</div>

Ve Denetleyicide:

$scope.filterSecId = function(items) {
    var result = {};
    angular.forEach(items, function(value, key) {
        if (!value.hasOwnProperty('secId')) {
            result[key] = value;
        }
    });
    return result;
}

jsfiddle : http://jsfiddle.net/bmleite/WA2BE/


9
Sonsuz (sindirilmiş) döngülerden kaçınmak için bu yaklaşıma dikkat etmek gerekir. Bkz. 6054 ve 705 . Narretz'in özeti : Kısacası, koleksiyonu ng-tekrarda geri döndürmek için işlevleri kullanmak bir anti-modeldir. Koleksiyonu bir kapsam özelliğine atamak ve bunun üzerinden döngü yapmak daha iyidir.
Joe23

3
Faydalı yorum. Bu beni bir döngüye atıyordu; Yinelenebilir herhangi bir şeyi filtreleyebilmeyi umuyordum. Çok teşekkürler. :)
Chris Krycho

3
Not: Bu artık mükemmel bir anti-modeldir. Angular 1.3 artık durumsuz filtrelere sahiptir ( egghead.io/lessons/… ), bu nedenle bunun için kesinlikle bir filtre oluşturmak isteyeceksiniz.
kentcdodds

8
@kentcdodds ücretsiz olmayan linkler yayınlamaz!
Sebastian

11
Neden tekrarlanan öğeye bir ng-if eklemiyorsunuz?
CarbonDry

45

Çözümüm, özel filtre oluşturup kullanmak olacaktır:

app.filter('with', function() {
  return function(items, field) {
        var result = {};
        angular.forEach(items, function(value, key) {
            if (!value.hasOwnProperty(field)) {
                result[key] = value;
            }
        });
        return result;
    };
});

Ve html'de:

 <div ng-repeat="(k,v) in items | with:'secId'">
        {{k}} {{v.pos}}
 </div>

1
ancak n * n kez döngüye girecektir.
maxisam

27

Ayrıca kullanabilirsiniz ng-repeatile ng-if:

<div ng-repeat="(key, value) in order" ng-if="value > 0">

2
Zeki. Bu çok zaman kazandırdı.
Safwan


11

Basitçe angular.filter modülünü kullanabilir ve ardından iç içe özelliklere göre bile filtre uygulayabilirsiniz .
bkz: jsbin
2 Örnekler:

JS:

angular.module('app', ['angular.filter'])
  .controller('MainCtrl', function($scope) {
  //your example data
  $scope.items = { 
    'A2F0C7':{ secId:'12345', pos:'a20' },
    'C8B3D1':{ pos:'b10' }
  };
  //more advantage example
  $scope.nestedItems = { 
    'A2F0C7':{
      details: { secId:'12345', pos:'a20' }
    },
    'C8B3D1':{
      details: { pos:'a20' }
    },
    'F5B3R1': { secId:'12345', pos:'a20' }
  };
});

HTML:

  <b>Example1:</b>
  <p ng-repeat="item in items | toArray: true | pick: 'secId'">
    {{ item.$key }}, {{ item }}
  </p>

  <b>Example2:</b>
  <p ng-repeat="item in nestedItems | toArray: true | pick: 'secId || details.secId' ">
    {{ item.$key }}, {{ item }}
  </p> 

21
Bunun angular.filterçekirdek açısal bir modül olmadığını ve onun yazarı olduğunuzu açıklamalısınız.
demisx

Görünüşe göre toArrayfiltre artık yok. filterFiltre hala nesnelere izin vermediği için bir yedek var mı ?
trysis

6

Biraz geç oldu, ama benzer bir filtre aradım ve şöyle bir şey kullanmayı bıraktım:

<div ng-controller="TestCtrl">
 <div ng-repeat="(k,v) in items | filter:{secId: '!!'}">
   {{k}} {{v.pos}}
 </div>
</div>

2
Bunu nasıl çalıştırdın? Yinelenen bir nesneye sahip bir filtre kullandığımda, Angular belgelerde beklenen temelde bir hata alıyorum.
tonestrike

1

Bu soru oldukça eski olmasına rağmen, çözümümü açısal 1 geliştiriciler için paylaşmak istiyorum. Amaç, orijinal açısal filtreyi yeniden kullanmak, ancak herhangi bir nesneyi bir dizi olarak şeffaf bir şekilde geçirmektir.

app.filter('objectFilter', function ($filter) {
    return function (items, searchToken) {
        // use the original input
        var subject = items;

        if (typeof(items) == 'object' && !Array.isArray(items)) {
            // or use a wrapper array, if we have an object
            subject = [];

            for (var i in items) {
                subject.push(items[i]);
            }
        }

        // finally, apply the original angular filter
        return $filter('filter')(subject, searchToken);
    }
});

şu şekilde kullanın:

<div>
    <input ng-model="search" />
</div>
<div ng-repeat="item in test | objectFilter : search">
    {{item | json}}
</div>

işte bir dalgıç


0

Zaten birden çok projede kullandığım genel bir filtreyi biraz daha yaptım:

  • nesne = filtrelenmesi gereken nesne
  • alan = o nesne içinde filtreleyeceğimiz alan
  • filtre = alanla eşleşmesi gereken filtrenin değeri

HTML:

<input ng-model="customerNameFilter" />
<div ng-repeat="(key, value) in filter(customers, 'customerName', customerNameFilter" >
   <p>Number: {{value.customerNo}}</p>
   <p>Name: {{value.customerName}}</p>
</div>

JS:

  $scope.filter = function(object, field, filter) {
    if (!object) return {};
    if (!filter) return object;

    var filteredObject = {};
    Object.keys(object).forEach(function(key) {
      if (object[key][field] === filter) {
        filteredObject[key] = object[key];
      }
    });

    return filteredObject;
  };
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.