Як перевірити довжину масиву, що спостерігається


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>

Але список $ .length не працює у випадку масиву, що спостерігається

Оновлення:

Здається, що (список $ | async) ?. довжина дає нам довжину, але наведений нижче код все ще не працює:

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

Хто-небудь, будь ласка, вкажіть, як я перевіряю довжину масиву, що спостерігається


Повідомлено на сайті github.com/angular/angular/issues/9641
Günter Zöchbauer

Відповіді:


178

Ви можете використовувати | 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: Неможливо прочитати властивість" length "of null"
Naveed Ahmed

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

6
Я спробував це, і це працює <div * ngIf = "(список $ | async) ?. length == 0"> Записів не знайдено. </div>
Naveed Ahmed

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

1
@ GünterZöchbauer мені здається, що перша asyncтруба вирішує дані, і тому моя наступна asyncтруба в циклі нічого не відображає. Або, можливо, *ngIfстворює додатковий обсяг і тому він не працює. Важко сказати. Але поки мій цикл загорнутий всередину, якщо він не відображає жодних даних. Якщо сам оцінює trueправильно.
Євген

31

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

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

чи не потрібно негайно після цього скасувати підписку?
Петро

Краще скасувати підписку на спостереження на onDestroyкомпоненті
ThPadelis


7

Хоча ця відповідь правильна

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

Майте на увазі, що якщо ви використовуєте http-клієнт для виклику бекенда (у більшості випадків ви це робите), ви отримаєте повторювані дзвінки до свого API, якщо у вас є більше одного списку $ | асинхронізація . Це тому, що кожен | async pipe створить нового абонента на ваш список $ спостерігається.


4

Це те, що працювало для мене -

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

Я отримую свої дані від httpClient async.

Всі інші варіанти тут не спрацювали для мене, що було невтішно. Особливо сексуальна (список $ | async) труба.

Баса ..


2

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

KAMRUL HASAN SHAHED має правильний підхід вище: Використовуйте асинхронну трубу один раз, а потім надайте псевдонім для результату, який ви можете використовувати в дочірніх вузлах.


1

Можна також скоротити:

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

Просто скористайтесь знаком оклику перед дужками.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.