Bagaimana cara memfilter (key, value) dengan ng-repeat di AngularJs?


113

Saya mencoba melakukan sesuatu seperti:

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

Bagian AngularJs:

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

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

Tapi entah bagaimana, itu menunjukkan semua item. Bagaimana cara memfilter (key, value)?


berikan beberapa contoh data untuk item. Atau beri kami biola;)
Robin Drexler

Ini bukan cara Anda membuat filter, lihat dokumentasi , dan seperti yang dikatakan Robin, harap contohnya.
Yahya KACEM

Saya sudah memberikan contoh lengkap dan saya tahu cara menggunakan filter. Saya hanya bertanya "bagaimana menggunakan filter dengan (key, value)".
Vural

indeks dan hitungan harus tersedia dalam cakupan itu iirc
Shanimal

Jawaban:


131

Filter sudut hanya dapat diterapkan ke array dan bukan objek, dari API sudut -

"Memilih subset item dari array dan mengembalikannya sebagai array baru."

Anda memiliki dua opsi di sini:
1) pindah $scope.itemske array atau -
2) pra-filter ng-repeatitem, seperti ini:

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

Dan di Kontroler:

$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
Seseorang perlu berhati-hati dengan pendekatan ini untuk menghindari loop tak terbatas (digest). Lihat 6054 dan 705 . Ringkasan oleh Narretz : Singkatnya, menggunakan fungsi untuk mengembalikan koleksi dalam ng-repeat adalah anti-pola. Lebih baik menetapkan koleksi ke properti cakupan, dan mengulanginya.
Joe23

3
Komentar yang berguna. Ini membuat saya bingung; Saya berharap dapat memfilter iterable apa pun . Terimakasih banyak. :)
Chris Krycho

3
Catatan: Ini adalah pola anti kinerja sekarang. Angular 1.3 memiliki filter stateless sekarang ( egghead.io/lessons/… ) jadi Anda pasti ingin membuat filter untuk ini.
kentcdodds

8
@kentcdodds jangan posting link yang tidak gratis!
Sebastian

11
Mengapa tidak menambahkan ng-if pada elemen berulang?
CarbonDry

45

Solusi saya adalah membuat filter khusus dan menggunakannya:

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

Dan di html:

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

1
namun, ini akan berulang n * n kali.
maxisam

27

Anda juga dapat menggunakan ng-repeatdengan ng-if:

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

2
Pintar. Ini menghemat banyak waktu.
Safwan


11

Anda cukup menggunakan modul angular.filter , dan kemudian Anda dapat memfilter bahkan menurut properti bertingkat.
lihat: jsbin
2 Contoh:

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
Anda harus mengungkapkan bahwa angular.filterbukan modul sudut inti dan Anda adalah pembuatnya.
demisx

Sepertinya toArrayfilter sudah tidak ada. Apakah ada penggantinya, karena filterfilter masih tidak memungkinkan adanya benda?
trisis

6

Ini agak terlambat, tetapi saya mencari filter serupa dan berakhir menggunakan sesuatu seperti ini:

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

2
Bagaimana Anda membuat ini bekerja? Ketika saya menggunakan filter dengan objek ng-diulang, saya mendapatkan kesalahan yang diharapkan berdasarkan dokumentasi Angular.
tonestrike

1

Meskipun pertanyaan ini agak lama, saya ingin membagikan solusi saya untuk developer angular 1. Intinya adalah hanya menggunakan kembali filter sudut asli, tetapi secara transparan meneruskan objek apa pun sebagai larik.

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

gunakan seperti ini:

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

di sini adalah plunker


0

Saya membuat lebih banyak filter umum yang telah saya gunakan di banyak proyek:

  • object = objek yang perlu difilter
  • field = bidang di dalam objek yang akan kita filter
  • filter = nilai filter yang harus sesuai dengan bidang

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;
  };
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.