Jak sprawdzić długość tablicy obserwowalnej

109

W moim komponencie Angular 2 mam tablicę Observable

list$: Observable<any[]>;

W moim szablonie mam

<div *ngIf="list$.length==0">No records found.</div>

<div *ngIf="list$.length>0">
    <ul>
        <li *ngFor="let item of list$ | async">item.name</li>
    </ul>
</div>

Ale lista $ .length nie działa w przypadku tablicy Observable.

Aktualizacja:

Wygląda na to, że (list $ | async) ?. length podaje nam długość, ale poniższy kod nadal nie działa:

<div>
    Length: {{(list$ | async)?.length}}
    <div *ngIf="(list$ | async)?.length>0">
        <ul>
            <li *ngFor="let item of (list$ | async)">
                {{item.firstName}}
            </li>
        </ul>
    </div>
</div>

Czy ktoś może poprowadzić, jak sprawdzić długość tablicy Observable.

Naveed Ahmed
źródło
Zgłoszono na github.com/angular/angular/issues/9641
Günter Zöchbauer

Odpowiedzi:

179

Możesz użyć | asyncrury:

<div *ngIf="(list$ | async)?.length==0">No records found.</div>

Aktualizacja - wersja Angular 6:

Jeśli ładujesz szkielet css, możesz tego użyć. Jeśli tablica nie zawiera elementów, wyświetli szablon css. Jeśli są dane, wypełnij ngFor.

<ul *ngIf="(list$| async)?.length > 0; else loading">
   <li *ngFor="let listItem of list$| async">
      {{ listItem.text }}
   </li>
</ul>

<ng-template #loading>
  <p>Shows when no data, waiting for Api</p>
  <loading-component></loading-component>
</ng-template>
Günter Zöchbauer
źródło
4
Próbowałem tego również, ale wyświetla błąd „TypeError: Cannot read property 'length' of null"
Naveed Ahmed
3
Trudno to określić na podstawie podanych przez Ciebie informacji. Spróbuj <div *ngIf="(list$ | async)?.length==0">No records found.</div>(dodano ?)
Günter Zöchbauer
6
Wypróbowałem to i działa <div * ngIf = "(list $ | async) ?. length == 0"> Brak rekordów. </div>
Naveed Ahmed
3
Dodatkowy ?jest wymagany, ponieważ list$jest ustawiany tylko wtedy, gdy Angular2 próbuje renderować widok po raz pierwszy. ?zapobiega obliczaniu reszty wyrażenia podrzędnego, dopóki część po lewej stronie ?zostanie zmieniona na != null(Elvis lub operator bezpiecznej nawigacji).
Günter Zöchbauer
1
@ GünterZöchbauer wygląda na to, że pierwsza potokka asyncrozwiązuje dane i dlatego moja następna asyncpotok w pętli nic nie wyświetla. A może *ngIftworzy dodatkowy zakres i dlatego nie działa. Ciężko powiedzieć. Ale podczas gdy moja pętla jest zawinięta wewnątrz if, nie wyświetla żadnych danych. Jeśli sam oceni truepoprawnie.
Eugene,
31

Rozwiązanie dla plików .ts:

     this.list.subscribe(result => {console.log(result.length)});
Pusty
źródło
czy nie jest konieczne natychmiastowe anulowanie subskrypcji później?
Peter
Lepiej zrezygnować z subskrypcji obserwowalnych na onDestroykomponencie
ThPadelis
16

W przypadku Angular 4+ spróbuj tego

<div *ngIf="list$ | async;let list">
    Length: {{list.length}}
    <div *ngIf="list.length>0">
        <ul>
            <li *ngFor="let item of list">
                {{item.firstName}}
            </li>
        </ul>
    </div>
</div>
MD KAMRUL HASAN SHAHED
źródło
7

Chociaż ta odpowiedź jest poprawna

<div *ngIf="(list$ | async)?.length === 0">No records found.</div>

Pamiętaj, że jeśli używasz klienta http do wywoływania backendu (w większości przypadków tak się dzieje), otrzymasz zduplikowane wywołania interfejsu API, jeśli masz więcej niż jedną listę $ | async . Dzieje się tak, ponieważ każdy | async potok utworzy nowego subskrybenta do twojej listy $ obserwowalne.

Andzej Maciusovic
źródło
4

To właśnie zadziałało dla mnie -

*ngIf="!photos || photos?.length===0"

Pobieram dane z asynchronicznego serwera httpClient.

Wszystkie inne opcje tutaj nie działały, co było rozczarowujące. Szczególnie seksowna (list $ | async) fajka.

Basa ..

Cwi Gregory Kaidanov
źródło
2

Twoje podejście ma inny poważny problem: wykorzystując potok asynchroniczny w swoim szablonie, w rzeczywistości rozpoczynasz tak wiele subskrypcji pojedynczego Observable.

KAMRUL HASAN SHAHED ma właściwe podejście powyżej: użyj potoku asynchronicznego raz, a następnie podaj alias dla wyniku, który możesz wykorzystać w węzłach podrzędnych.

Harry Beckwith
źródło
1

Można również skrócić:

<div *ngIf="!(list$ | async)?.length">No records found.</div>

Po prostu użyj wykrzyknika przed nawiasem.

Daniyal Lukmanov
źródło
-3

jonowy 4

<div *ngIf="(items | async)?.length==0">No records found.</div>

zadziałało, kiedy usunąłem $znak

Ahmed Al-hajri
źródło