AngularJS ng-ulangi menangani daftar kasus kosong

377

Saya pikir ini akan menjadi hal yang sangat umum, tetapi saya tidak dapat menemukan cara menanganinya di AngularJS. Katakanlah saya memiliki daftar acara dan ingin menampilkannya dengan AngularJS, maka itu cukup mudah:

<ul>
    <li ng-repeat="event in events">{{event.title}}</li>
</ul>

Tetapi bagaimana saya menangani kasing ketika daftar kosong? Saya ingin memiliki kotak pesan di tempat daftar dengan sesuatu seperti "Tidak ada acara" atau serupa. Satu-satunya hal yang akan mendekati adalah ng-switchdengan events.length(bagaimana saya memeriksa jika kosong ketika suatu objek dan bukan array?), Tetapi apakah itu benar-benar satu-satunya pilihan yang saya miliki?

Prinzhorn
sumber
4
@ Artem jawabannya baik (+1). Inilah diskusi grup google yang menggunakan filter, untuk referensi / perbandingan: groups.google.com/d/topic/angular/wR06cN5oVBQ/discussion
Mark Rajcok

Jawaban:

569

Anda dapat menggunakan ngShow .

<li ng-show="!events.length">No events</li>

Lihat contoh .

Atau Anda bisa menggunakan ngHide

<li ng-hide="events.length">No events</li>

Lihat contoh .

Untuk objek, Anda dapat menguji Object.keys .

Artem Andreev
sumber
1
Memang @ArtemAndreev. Ketika "events" adalah array kosong, ia mengembalikan true walaupun array kosong
Rob Juurlink
Saya pikir ada masalah dengan Object.keys: jsfiddle.net/J9b5z , bagaimana Anda menangani ini?
Dani
5
nh-show berfungsi id kasus saya tetapi tidak memperbarui keadaan ketika saya meletakkan filter dan tidak ada yang kembali. Juga objek muncul pada pemuatan pertama dan menghilang ketika proses pengulangan dilakukan pada pemuatan halaman.
dvdmn
1
@Dani coba menambahkan fungsi ke controller Anda yang melakukan tes. Anda kemudian dapat memohon arahan dengan ng-hide="hasEvents()".
Tn. S
Ya terima kasih. Namun, saya berharap akan ada cara yang lebih elegan tanpa "mencemari" controller.
Dani
370

Dan jika Anda ingin menggunakan ini dengan daftar yang difilter di sini adalah trik yang rapi:

<ul>
    <li ng-repeat="item in filteredItems  = (items | filter:keyword)">
        ...
    </li>
</ul>
<div ng-hide="filteredItems.length">No items found</div>
Konrad 'ktoso' Malawski
sumber
3
Sangat berguna. Typo though with "filteredFragments".
ravishi
1
Manis! Ekspresi di dalam ng-repeat terlihat aneh. Apakah Anda bisa menjelaskannya? Terima kasih!!
MK Safi
7
@MKSafi, itu membuat variabel baru pada ruang lingkup yang disebut filteredItemsdan menetapkan nilainya ke (items | filter:keyword)- dengan kata lain, array dikembalikan oleh filter
AlexFoxGill
17
IYA! Ninja plus poin! Ini menghemat sudut dari mengevaluasi filter kompleks dua kali!
markmarijnissen
2
Juga, tampaknya ada beberapa batasan dalam hal ini dengan beberapa filter, seperti "face in filteredFaces = faces|filter:{deleted: true} | orderBy:'text'tapi saya setuju dengan semua orang, ini adalah trik yang luar biasa.
Fitter Man
29

Anda mungkin ingin memeriksa petunjuk angular-ui ui-if jika Anda hanya ingin menghapus uldari DOM ketika daftar kosong:

<ul ui-if="!!events.length">
    <li ng-repeat="event in events">{{event.title}}</li>
</ul>
Mortimer
sumber
1
Terima kasih. Terasa lebih bersih daripada hanya menyembunyikannya.
Prinzhorn
@ Portimer: jadi dalam hal ini apakah kita perlu angular-ui?
Shibbir Ahmed
Anda dapat menggunakan ng-hidetanpa angular-ui, tetapi itu hanya akan menyembunyikan node, itu tidak akan menghapusnya dari pohon DOM. Dengan ui-ifarahan angular-ui , itu akan menghapus simpul DOM. Jadi, Anda setidaknya perlu menambahkan ui-ifarahan dari kode angular-ui ke kode Anda sendiri.
Mortimer
21
sudut terbaru telah ng-iftermasuk!
markmarijnissen
4
Catatan yang ng-ifmembuat lingkup baru, di mana ng-hidetidak. Ini mungkin menyebabkan perilaku yang tidak terduga.
Arnold Daniels
29

Dengan versi angular yang lebih baru, jawaban yang benar untuk pertanyaan ini adalah dengan menggunakan ng-if:

<ul>
  <li ng-if="list.length === 0">( No items in this list yet! )</li>
  <li ng-repeat="item in list">{{ item }}</li>
</ul>

Solusi ini tidak akan berkedip ketika daftar akan diunduh karena daftar harus ditentukan dan dengan panjang 0 untuk pesan yang akan ditampilkan.

Berikut adalah penyedot untuk menunjukkannya digunakan: http://plnkr.co/edit/in7ha1wTlpuVgamiOblS?p=preview

Kiat: Anda juga dapat menampilkan teks atau pemintal yang memuat:

  <li ng-if="!list">( Loading... )</li>
Pylinux
sumber
23
<ul>
    <li ng-repeat="item in items | filter:keyword as filteredItems">
        ...
    </li>
    <li ng-if="filteredItems.length===0">
        No items found
    </li>
</ul>

Ini mirip dengan @Konrad 'ktoso' Malawski tetapi sedikit lebih mudah diingat.

Diuji dengan Angular 1.4

Bernard
sumber
3
Maksud Andang-if='!filteredItems.length'
abrunet
Bagaimana Anda melakukan ini dengan beberapa filter?
Jordash
@Jordash Teruslah mengepalkannya item in items | filter: ... | filter: ...
Bernard
Perbaikan yang bagus dan lebih lanjut adalah<li ng-if="!filteredItems.length">
Matty J
Ini bagus. Saya telah menggunakan banyak metode yang lebih kotor sebelumnya sepertiitem in (filteredItems = (items | filter: someFilter))
Firze
6

Berikut ini pendekatan yang berbeda menggunakan CSS, bukan JavaScript / AngularJS.

CSS:

.emptymsg {
  display: list-item;
}

li + .emptymsg {
  display: none;
}

Markup:

<ul>
    <li ng-repeat="item in filteredItems"> ... </li>
    <li class="emptymsg">No items found</li>
</ul>

Jika daftar kosong, <li ng-repeat = "item in filteredItems">, dll. Akan dikomentari dan akan menjadi komentar dan bukan elemen li.

Miriam Salzer
sumber
Pertanyaan mengatakan "Saya ingin memiliki kotak pesan di tempat di mana daftar berada". Saya juga berpikir itu tidak menguntungkan untuk memisahkan logika menjadi stylesheet s. Sulit untuk mempertahankan dan meminta masalah.
Prinzhorn
1
@Rinzhorn, saya pikir menggunakan CSS adalah keuntungan karena logikanya sangat sederhana dan mudah dirawat, CSS dapat digunakan kembali untuk daftar lain, dan tidak bergantung pada JavaScript. Tidak diperlukan pendengar atau pengamat tambahan. Pesannya bisa ditata agar terlihat seperti kotak, saya hanya tidak membuat jawaban sederhana.
Miriam Salzer
Beberapa bulan terlambat, memang, tapi saya setuju dengan Miriam, saya pikir jawaban ini jenius.
Jon Combe
2

Anda dapat menggunakan ng-switch ini:

<div ng-app ng-controller="friendsCtrl">
  <label>Search: </label><input ng-model="searchText" type="text">
  <div ng-init="filtered = (friends | filter:searchText)">
  <h3>'Found '{{(friends | filter:searchText).length}} friends</h3>
  <div ng-switch="(friends | filter:searchText).length">
    <span class="ng-empty" ng-switch-when="0">No friends</span>
    <table ng-switch-default>
      <thead>  
        <tr>
          <th>Name</th>
          <th>Phone</th>
        </tr>
      </thead>
      <tbody>
      <tr ng-repeat="friend in friends | filter:searchText">
        <td>{{friend.name}}</td>
        <td>{{friend.phone}}</td>
      </tr>
    </tbody>
  </table>
</div>
LukitaBrands
sumber
1

Anda dapat menggunakan askata kunci untuk merujuk koleksi di bawah ng-repeatelemen:

<table>
    <tr ng-repeat="task in tasks | filter:category | filter:query as res">
        <td>{{task.id}}</td>
        <td>{{task.description}}</td>
    </tr>
    <tr ng-if="res.length === 0">
        <td colspan="2">no results</td>
    </tr>
</table>
Damian Czapiewski
sumber
0

saya biasanya menggunakan ng-show

<li ng-show="variable.length"></li>

di mana variabel yang Anda tetapkan misalnya

<div class="list-group-item" ng-repeat="product in store.products">
   <li ng-show="product.length">show something</li>
</div>
Ezequiel García
sumber
0

Anda dapat menggunakan ng-jika karena ini bukan render di halaman html dan Anda tidak melihat tag html Anda di periksa ...

<ul ng-repeat="item in items" ng-if="items.length > 0">
    <li>{{item}}<li>
</ul>
<div class="alert alert-info">there is no items!</div>
pejman
sumber