Açısal JS tekrarlama tutma kolu boş liste kutusu


377

Bunun çok yaygın bir şey olacağını düşündüm, ancak AngularJS'de nasıl ele alacağımı bulamadım. Diyelim ki olayların bir listesi var ve bunları AngularJS ile çıktılamak istiyorum, o zaman bu oldukça kolay:

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

Ancak liste boşken durumu nasıl ele alabilirim? Listenin "Olay yok" veya benzeri bir şey olduğu bir ileti kutusu olmasını istiyorum. Yaklaşan tek şey ng-switchile events.length(bir nesne değil, bir dizi değil, boş olup olmadığını nasıl kontrol ederim?), Ama gerçekten sahip olduğum tek seçenek bu mu?


4
@ Artem'in cevabı iyidir (+1). İşte referans / karşılaştırma için filtre kullanan bir google grup tartışması: groups.google.com/d/topic/angular/wR06cN5oVBQ/discussion
Mark Rajcok

Yanıtlar:


569

NgShow'u kullanabilirsiniz .

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

Bkz örnek .

Veya ngHide kullanabilirsiniz

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

Bkz örnek .

Nesne için Object.keys test edebilirsiniz .


1
Gerçekten de @ArtemAndreev. "Olaylar" boş bir dizi olduğunda, dizi boş olsa bile true değerini döndürür
Rob Juurlink

Object.keys ile ilgili bir sorun olduğunu düşünüyorum: jsfiddle.net/J9b5z , bunu nasıl halledersiniz?
Dani

5
nh-show benim durumumda çalıştı ama bir filtre koymak ve hiçbir şey geri döndüğünde durumu güncelleştirmez. Ayrıca nesne ilk yüklemede görünür ve sayfa yüklendiğinde tekrarlama işlemi tamamlandığında kaybolur.
dvdmn

1
@Dani, kontrol cihazınıza testi gerçekleştiren bir işlev eklemeyi deneyin. Daha sonra direktifi ile başlatabilirsiniz ng-hide="hasEvents()".
Bay S

Evet teşekkürler. Ancak, denetleyiciyi "kirletmeden" daha zarif bir yol olacağını umuyordum.
Dani

370

Ve bunu filtrelenmiş bir listeyle kullanmak istiyorsanız, burada düzgün bir numara var:

<ul>
    <li ng-repeat="item in filteredItems  = (items | filter:keyword)">
        ...
    </li>
</ul>
<div ng-hide="filteredItems.length">No items found</div>

3
Çok kullanışlı. Ancak "filterFragments" ile yazım hatası.
ravishi

1
Tatlı! Yine de ng-repeat içindeki ifade garip görünüyor. Bunu açıklamak için bir şansın var mı? Teşekkürler!!
MK Safi

7
@MKSafi, kapsamda yeni bir değişken oluşturuyor filteredItemsve değerini (items | filter:keyword)- yani başka bir deyişle, filtre tarafından döndürülen diziyi
AlexFoxGill

17
EVET! Ninja artı puan! Bu açısal karmaşık bir filtreyi iki kez değerlendirmekten kurtarır!
markmarijnissen

2
Ayrıca, birden fazla filtreyle bu konuda bazı sınırlamalar var gibi görünüyor, "face in filteredFaces = faces|filter:{deleted: true} | orderBy:'text'ama herkesle aynı fikirdeyim, bu harika bir numara.
Tesisatçısı

29

Liste boşken DOM'dan kaldırmak istiyorsanız açısal-ui yönergesine göz atmak ui-ifisteyebilirsiniz ul:

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

1
Teşekkürler. Saklamaktan daha temiz hissettiriyor.
Prinzhorn

@ Mortimer: Peki bu durumda açısal-ui'ye ihtiyacımız var mı?
Shibbir Ahmed

ng-hideaçısal-ui olmadan kullanabilirsiniz , ancak düğümü gizleyecek, DOM ağacından kaldırmayacaktır. Açısal-ui ui-ifyönergesiyle DOM düğümünü kaldıracaktır. Bu nedenle, en azından ui-ifaçısal-ui kodundan yönergeyi kendi kodunuza eklemeniz gerekir.
Mortimer

21
yeni açısal ng-ifdahil!
markmarijnissen

4
Bunun ng-ifyeni bir kapsam oluşturduğunu unutmayın , burada ng-hidedeğil. Bu beklenmeyen davranışlara neden olabilir.
Arnold Daniels

29

Angularjs'ın yeni sürümlerinde bu sorunun doğru cevabı kullanmaktır 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>

Bu çözüm, liste indirilmek üzereyken, liste tanımlanması gerektiğinden ve iletinin görüntülenmesi için 0 uzunluğunda olduğu için titremez.

İşte kullanımda göstermek için bir dalgıç: http://plnkr.co/edit/in7ha1wTlpuVgamiOblS?p=preview

İpucu: Ayrıca bir yükleme metni veya döndürücü de gösterebilirsiniz:

  <li ng-if="!list">( Loading... )</li>

23
<ul>
    <li ng-repeat="item in items | filter:keyword as filteredItems">
        ...
    </li>
    <li ng-if="filteredItems.length===0">
        No items found
    </li>
</ul>

Bu @Konrad 'ktoso' Malawski'ye benzer, ancak hatırlanması biraz daha kolaydır.

Açısal 1.4 ile test edildi


3
Demek istedinizng-if='!filteredItems.length'
abrunet

Bunu birden çok filtreyle nasıl yaparsınız?
Jordash

@Jordash Sadece onları piping devam item in items | filter: ... | filter: ...
Bernard

Güzel, daha fazla ayrıntı<li ng-if="!filteredItems.length">
Matty J

Bu harika. Daha önce gibi çok daha kirli bir yöntem kullanıyordumitem in (filteredItems = (items | filter: someFilter))
Firze

6

İşte JavaScript / AngularJS yerine CSS kullanarak farklı bir yaklaşım.

CSS:

.emptymsg {
  display: list-item;
}

li + .emptymsg {
  display: none;
}

İşaretleme:

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

Liste boşsa, <li ng-repeat = "filterItems içindeki öğe"> vb. Yorumlanır ve li öğesi yerine yorum haline gelir.


Soru, "Listenin bulunduğu yerde bir mesaj kutusu olmasını istiyorum" diyor. Ayrıca mantığı stil sayfasına ayırmanın dezavantajlı olduğunu düşünüyorum. Bakımı zor ve sorun istiyor.
Prinzhorn

1
@Prinzhorn, mantığın çok basit ve bakımı kolay olduğu için CSS kullanmanın bir avantaj olduğunu düşünüyorum, CSS diğer listeler için tekrar kullanılabilir ve JavaScript'e güvenmiyor. Ek dinleyici veya izleyici gerekmez. Mesaj bir kutuya benzeyecek şekilde şekillendirilebilir, cevabı basit tutmadım.
Miriam Salzer

Birkaç ay geç kaldım, ama Miriam'a katılıyorum, bu cevabın deha olduğunu düşünüyorum.
Jon Combe

2

Bu ng anahtarını kullanabilirsiniz:

<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>

1

asBir ng-repeatöğenin altındaki bir koleksiyona başvuruda bulunmak için anahtar kelime kullanabilirsiniz :

<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>

0

genellikle ng-show kullanıyorum

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

örneğin tanımladığınız değişken

<div class="list-group-item" ng-repeat="product in store.products">
   <li ng-show="product.length">show something</li>
</div>

0

ng-if kullanabilirsiniz, çünkü bu html sayfasında görüntülenmez ve html etiketinizi incelemede görmezsiniz ...

<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>
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.