Bagaimana cara memfilter array dengan AngularJS dan menggunakan properti objek yang difilter sebagai atribut ng-model?

122

Jika saya memiliki array objek, dan saya ingin mengikat model Angular ke properti salah satu elemen berdasarkan filter, bagaimana cara melakukannya? Saya bisa menjelaskan lebih baik dengan contoh konkret:

HTML:

<!DOCTYPE html>
<html ng-app>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
        <meta charset=utf-8 />
        <title>JS Bin</title>
    </head>
    <body ng-controller="MyCtrl">
        <input ng-model="results.year">
        <input ng-model="results.subjects.title | filter:{grade:'C'}">
    </body>
</html>

Pengontrol:

function MyCtrl($scope) {
  $scope.results = {
    year:2013,
    subjects:[
      {title:'English',grade:'A'},
      {title:'Maths',grade:'A'},
      {title:'Science',grade:'B'},
      {title:'Geography',grade:'C'}
    ]
  };
}

JSBin: http://jsbin.com/adisax/1/edit

Saya ingin memfilter input kedua ke subjek dengan nilai 'C', tetapi saya tidak ingin mengikat model ke nilai ; Saya ingin mengikatnya dengan judul mata pelajaran yang memiliki nilai 'C'.

Apakah ini mungkin, dan jika demikian, bagaimana melakukannya?

Bernhard Hofmann
sumber

Jawaban:

127
<div ng-repeat="subject in results.subjects | filter:{grade:'C'}">
    <input ng-model="subject.title" />
</div>
JB Nizet
sumber
1
Saya melihat ke mana Anda pergi dengan itu, tapi saya benar-benar tidak menginginkan repeater. Properti yang akan saya gunakan untuk memfilter adalah kolom identitas, jadi itu unik. Tetapi saya melihat bahwa ini akan menjadi cara yang tepat untuk menyelesaikan masalah umum.
Bernhard Hofmann
1
ini adalah tutorial untuk orang italia :) dev.stasbranger.com/post/77190983049/…
Silvio Troia
10
ini sangat membantu, dan untuk kebalikan (segala sesuatu selain C), ini akan berhasil:filter:{grade:'!'+'C'}
pulkitsinghal
2
Bisakah Anda melakukan hal yang sama dengan grade array? Dalam kasus saya, saya membangun array nilai saya dari tampilan pohon dan ingin memfilter hasilnya untuk mereka yang ada di dalam array.
Juan Carlos Oropeza
157

Anda dapat menggunakan filter "filter" di pengontrol Anda untuk mendapatkan semua nilai "C". Mendapatkan elemen pertama dari larik hasil akan memberi Anda judul subjek yang memiliki nilai "C".

$scope.gradeC = $filter('filter')($scope.results.subjects, {grade: 'C'})[0];

http://jsbin.com/ewitun/1/edit

Hal yang sama dengan ES6 biasa:

$scope.gradeC = $scope.results.subjects.filter((subject) => subject.grade === 'C')[0]
Oliver
sumber
saya minta maaf saya tidak mengikuti filter kedua itu ('filter') dapatkah Anda menjelaskannya sedikit lagi?
Winnemucca
1
@stevek Itulah nama filternya. Metode filter () memberi Anda filter. Hanya saja filter itu disebut filter karena menyaring sebuah array. Ini akan terlihat seperti ini dengan filter mata uang: $ filter ('currency') (jumlah, simbol, fractionSize) Periksa dokumen di sini: docs.angularjs.org/api/ng/filter
Oliver
61

Berikut adalah JSBin yang dimodifikasi dengan contoh yang berfungsi:

http://jsbin.com/sezamuja/1/edit

Inilah yang saya lakukan dengan filter di masukan:

<input ng-model="(results.subjects | filter:{grade:'C'})[0].title">
lukeatdesignworks
sumber
1
Ini yang sebenarnya. Inilah kekuatannya. Ini caranya. Saya pergi dengan ini dan sekarang saya bahagia.
pengguna1576978
13

perlu diketahui, jika Anda menggunakan $ filter seperti ini:

$scope.failedSubjects = $filter('filter')($scope.results.subjects, {'grade':'C'});

dan Anda kebetulan memiliki nilai lain untuk, Oh saya tidak tahu, CC atau AC atau C + atau CCC itu menarik mereka ke. Anda perlu menambahkan persyaratan untuk pencocokan tepat:

$scope.failedSubjects = $filter('filter')($scope.results.subjects, {'grade':'C'}, true);

Ini benar-benar membunuh saya ketika saya menarik beberapa detail komisi seperti ini:

var obj = this.$filter('filter')(this.CommissionTypes, { commission_type_id: 6}))[0];

hanya dipanggil karena bug karena menarik ID komisi 56 daripada 6.

Menambahkan kekuatan sebenarnya menjadi pencocokan tepat.

var obj = this.$filter('filter')(this.CommissionTypes, { commission_type_id: 6}, true))[0];

Namun tetap saja, saya lebih suka ini (saya menggunakan skrip jenis, maka "Let" dan =>):

let obj = this.$filter('filter')(this.CommissionTypes, (item) =>{ 
             return item.commission_type_id === 6;
           })[0];

Saya melakukan itu karena, pada suatu saat nanti, saya mungkin ingin mendapatkan lebih banyak info dari data yang difilter, dll ... memiliki fungsi tepat di sana seperti membiarkan tudung terbuka.

Daniel Morris
sumber
Saya mengalami kesalahan yang sama seperti Anda, terima kasih atas petunjuk dengan parameter boolean ketiga. Tidak menyadarinya.
Georg Leber
12

jika Anda ingin membuat daftar hasil yang terpisah di pengontrol, Anda dapat menerapkan filter

function MyCtrl($scope, filterFilter) {
  $scope.results = {
    year:2013,
    subjects:[
      {title:'English',grade:'A'},
      {title:'Maths',grade:'A'},
      {title:'Science',grade:'B'},
      {title:'Geography',grade:'C'}
    ]
  };
  //create a filtered array of results 
  //with grade 'C' or subjects that have been failed
  $scope.failedSubjects = filterFilter($scope.results.subjects, {'grade':'C'});
}

Kemudian Anda dapat mereferensikan FailSubjects dengan cara yang sama seperti Anda mereferensikan objek hasil

Anda dapat membaca lebih lanjut tentangnya di sini https://docs.angularjs.org/guide/filter

karena sudut jawaban ini telah memperbarui dokumentasi, mereka sekarang merekomendasikan untuk memanggil filter

// update 
// eg: $filter('filter')(array, expression, comparator, anyPropertyKey);
// becomes
$scope.failedSubjects = $filter('filter')($scope.results.subjects, {'grade':'C'});
Kieran
sumber
apa itu filterFilter? apakah itu layanan atau arahan? di mana kode untuk filterFilter?
Mou
itu adalah layanan sudut. Lihat contoh pertama pada tautan di atas. (dalam file scripts.js)
Kieran
meskipun mereka telah mengubah filterFilter dokumentasi masih berfungsi ..
Kieran
4

Anda juga dapat menggunakan fungsi dengan $filter('filter'):

var foo = $filter('filter')($scope.results.subjects, function (item) {
  return item.grade !== 'A';
});
Nelu
sumber
4

Jika Anda menggunakan ES6, Anda dapat:

var sample = [1, 2, 3]

var result = sample.filter(elem => elem !== 2)

/* output */
[1, 3]

Juga perhatikan filter tidak memperbarui array yang ada itu akan mengembalikan array baru yang difilter setiap saat.

Diego Venâncio
sumber
0

Menerapkan filter yang sama di HTML dengan banyak kolom, contoh saja:

 variable = (array | filter : {Lookup1Id : subject.Lookup1Id, Lookup2Id : subject.Lookup2Id} : true)
Amay Kulkarni
sumber