Как проверить длину наблюдаемого массива


109

В моем компоненте Angular 2 у меня есть наблюдаемый массив

list$: Observable<any[]>;

В моем шаблоне у меня есть

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

Но list $ .length не работает в случае массива Observable.

Обновить:

Кажется, что (list $ | async) ?. length дает нам длину, но приведенный ниже код все еще не работает:

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

Может ли кто-нибудь указать, как проверить длину наблюдаемого массива.


Ответы:


179

Вы можете использовать | asyncтрубу:

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

Обновление - угловая версия 6:

Если вы загружаете css Skeleton, вы можете использовать это. Если в массиве нет элементов, он отобразит шаблон css. Если есть данные, заполните 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>

4
Я тоже пробовал это, но выдает ошибку «TypeError: Cannot read property 'length' of null»
Навид Ахмед

3
Трудно узнать из предоставленной вами информации. Try <div *ngIf="(list$ | async)?.length==0">No records found.</div>(добавлено ?)
Günter Zöchbauer

6
Я пробовал это, и он работает <div * ngIf = "(list $ | async) ?. length == 0"> Записей не найдено. </div>
Навид Ахмед

3
Дополнительное значение ?требуется, потому что list$оно устанавливается только после того, как Angular2 попытается отобразить представление в первый раз. ?предотвращает оценку остальной части подвыражения до тех пор, пока левая часть не ?станет != null(Элвис или оператор безопасной навигации).
Günter Zöchbauer

1
@ GünterZöchbauer, мне кажется, этот первый asyncканал разрешает данные, и поэтому мой следующий asyncканал в цикле ничего не отображает. Или, может быть, *ngIfсоздает дополнительную область, и поэтому она не работает. Трудно сказать. Но пока мой цикл заключен внутри if, он не отображает никаких данных. Если сам оценивает trueправильно.
Евгений

31

Решение для .ts-файлов:

     this.list.subscribe(result => {console.log(result.length)});

разве после этого не нужно сразу отказываться от подписки?
Питер

Лучше отказаться от подписки на наблюдаемые по onDestroyкомпоненту
ThPadelis

16

Для Angular 4+ попробуйте это

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

7

Хотя это правильный ответ

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

Имейте в виду, что если вы используете http-клиент для вызова серверной части (в большинстве случаев вы это делаете), вы получите дублирующиеся вызовы к вашему API, если у вас есть более одного списка $ | асинхронный . Это потому, что каждый | async pipe создаст нового подписчика в вашем списке $ observable.


4

Вот что сработало для меня -

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

Я получаю свои данные из httpClient async.

Все остальные варианты здесь не работали, что меня разочаровало. Особенно секси (list $ | async) канал.

Баса ..


2

У вашего подхода есть еще одна серьезная проблема: многократно используя асинхронный канал в своем шаблоне, вы фактически запускаете столько подписок на один Observable.

У KAMRUL HASAN SHAHED правильный подход, описанный выше: используйте асинхронный конвейер один раз, а затем укажите псевдоним для результата, который вы можете использовать в дочерних узлах.


1

Также можно сократить:

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

Просто используйте восклицательный знак перед скобкой.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.