angular ng-repeat lewati item jika cocok dengan ekspresi

91

Saya mencari cara untuk memberitahu angular untuk melewati sebuah item dalam ng-repeat jika cocok dengan ekspresi, pada dasarnya continue;

Dalam pengontrol:

$scope.players = [{
    name_key:'FirstPerson', first_name:'First', last_name:'Person'
}, {
    name_key:'SecondPerson', first_name:'Second', last_name:'Person'
}]

Sekarang di template saya, saya ingin menunjukkan kepada semua orang yang tidak cocok name_key='FirstPerson'. Saya pikir itu harus menjadi filter jadi saya menyiapkan Plunkr untuk bermain-main dengannya tetapi belum beruntung. Percobaan Plunkr

aron.duby
sumber
Saya mencoba untuk memahami: apakah Anda ingin menampilkan semua item kecuali menunjukkan siapa yang cocok dan siapa yang tidak? atau hanya menyaring?
Maxim Shoustin

Jawaban:

144

Seperti yang disarankan oleh @Maxim Shoustin , cara terbaik untuk mencapai apa yang Anda inginkan adalah dengan menggunakan filter khusus.
Tetapi ada cara lain, salah satunya adalah dengan menggunakan ng-ifdirektif pada elemen yang sama Anda meletakkan ng-repeatdirektif (juga, ini plunkernya ):

<ul>
    <li ng-repeat="player in players" ng-if="player.name_key!='FirstPerson'"></li>
</ul>

Hal ini mungkin memberikan kerugian kecil dari sudut pandang estetika, tetapi memiliki keuntungan besar bahwa pemfilteran Anda dapat didasarkan pada aturan yang tidak terkait erat dengan playersarray dan yang dapat dengan mudah mengakses data lain dalam cakupan aplikasi Anda:

  <li 
      ng-repeat="player in players" 
      ng-if="app.loggedIn && player.name != user.name"
  ></li>

Perbarui
Seperti yang dinyatakan, ini adalah salah satu solusi untuk masalah seperti ini dan mungkin sesuai atau tidak sesuai dengan kebutuhan Anda.
Seperti yang ditunjukkan di komentar, ng-ifis a directive, yang sebenarnya berarti mungkin melakukan lebih banyak hal di latar belakang daripada yang Anda harapkan.
Misalnya, ng-if membuat cakupan baru dari induknya :

Cakupan yang dibuat dalam ngIf mewarisi dari lingkup induknya menggunakan pewarisan prototypal.

Ini biasanya tidak memengaruhi perilaku normal, tetapi untuk mencegah kasus yang tidak terduga, Anda harus mengingatnya sebelum menerapkan.

gion_13
sumber
inilah yang saya cari, saya tahu pasti ada cara singkat dan manis untuk melakukannya tanpa filter khusus. Terima kasih!
aron.duby
Catatan: ada beberapa perilaku cakupan ng-if yang bisa rumit. Saya mencoba metode ini dan itu menyebabkan masalah di tempat lain. Yaitu, saya memiliki arahan "pengamat" yang menyiarkan acara ketika pengulang selesai. Setelah menambahkan ng-if ke repeater ini, peristiwa itu tidak lagi diaktifkan. Filter khusus mungkin merupakan cara terbersih untuk digunakan.
claywhipkey
@claywhipkey Anda benar, cara terbersih adalah menggunakan filter, tetapi itu tidak cocok untuk semua kasus. Anyway, thx atas komentar dan Anda dapat melihat bahwa saya telah menambahkan kepala update dalam jawabannya hanya untuk membuat orang menyadari implikasi dari menggunakan direktif untuk menyaring data.
gion_13
43

Saya tahu ini adalah yang lama, tetapi jika seseorang akan mencari solusi lain yang mungkin, berikut adalah cara lain untuk menyelesaikannya - gunakan fungsi filter standar :

Objek: Objek pola dapat digunakan untuk memfilter properti tertentu pada objek yang dikandung oleh larik. Misalnya predikat {name: "M", phone: "1"} akan mengembalikan array item yang memiliki nama properti yang berisi "M" dan telepon properti yang berisi "1". ... Predikat dapat dinegasikan dengan mengawali string dengan!. Misalnya predikat {name: "! M"} akan mengembalikan array item yang memiliki nama properti tidak mengandung "M".

Jadi untuk contoh TS, sesuatu seperti ini harus dilakukan:

<ul>
    <li ng-repeat="player in players | filter: { name_key: '!FirstPerson' }"></li>
</ul>

Tidak perlu menulis filter khusus, tidak perlu menggunakan ng-ifdengan cakupan barunya.

Ilya Luzyanin
sumber
Sederhana pada intinya. Tidak ada filter khusus atau cakupan baru yang dibuat seperti yang dinyatakan oleh penulis. Sempurna untuk melewatkan satu nilai dalam daftar.
mbokil
Saya pikir Anda perlu menghilangkan 'player' dari 'player.name_key' - jadi itu hanya akan menjadi "{name_key: '! FirstPerson'}" pada contoh di atas.
smithml
Saya tidak pernah bisa membuat Angular bermain bagus dengan kunci kosong. Apakah ada semacam trik untuk menggunakan filter bawaan yang setara player in players | filter: { name_key: '' }? Arahan khusus itu tidak akan cocok hanya dengan pemain dengan no / an kosong name_key. Kebalikannya, name_key: '!'dimaksudkan untuk memilih pemain dengan non-kosong name_keyjuga tidak akan berfungsi.
Eric L.
Anda dapat memeriksa jawaban ini .
Ilya Luzyanin
4
Berhati-hatilah bahwa ini hanya berfungsi dengan array, bukan dengan properti objek dalam kasus seperting-repeat="(key, val) in player"
David Diez
19

Anda dapat menggunakan filter khusus saat Anda menerapkan ng-repeat. Sesuatu seperti:

 data-ng-repeat="player in players |  myfilter:search.name

myfilter.js:

app.filter('myfilter', function() {


   return function( items, name) {
    var filtered = [];

    angular.forEach(items, function(item) {

      if(name == undefined || name == ''){
        filtered.push(item);
        }

      /* only if you want start With*/
      // else if(item.name_key.substring(0, name.length) !== name){
      //   filtered.push(item);
      // }

      /* if you want contains*/
      // else if(item.name_key.indexOf(name) < 0 ){
      //   filtered.push(item);
      // }

       /* if you want match full name*/
       else if(item.name_key !== name ){
        filtered.push(item);
      }
    });

    return filtered;
  };
});

Demo Plunker

Maxim Shoustin
sumber
Terima kasih atas pekerjaan yang Anda lakukan untuk ini. Ini pasti benar tetapi saya akhirnya menggunakan jawaban @ gion_13 dengan mudah dalam kode jadi saya pikir saya lebih baik menandainya sebagai jawaban yang diterima
aron.duby