/ / Angular 4 async із завантаженням та відображенням, коли порожній - angular, async-await

Кутовий 4 асинхронний з завантаженням і відображенням, коли порожній - кутовий, async-await

У мене є Angular компонент, який отримує послугу CatalogServiceвводиться:

export class CatalogListComponent implements OnInit {
catalog$: Observable<MovieResponseItem[]>;
constructor(private catalogService: CatalogService) {}
ngOnInit() {
this.catalog$ = this.catalogService.userCatalog;
}
}

Ця послуга повертає Observable<MovieResponseItem[]> на власність userCatalog:

@Injectable()
export class CatalogService {
get userCatalog(): Observable<MovieResponseItem[]> {
return this._userCatalogSubject.asObservable();
}
}

The MovieResponseItemце просто простий інтерфейс:

export interface MovieResponseItem {
title: string;
}

Тепер я хочу повторити елементи та відобразити анімацію завантаження, поки каталог запитує базову службу щодо даних (це займає деякий час) - це працює. Ось шаблон, що використовується:

<div *ngIf="(catalog$ | async)?.length > 0; else loading">
<ng-container *ngFor="let item of catalog$ | async">
<div>{{item.title}}</div>
<ng-container>
</div>
<ng-template #loading>loading animation...</ng-template>

Це, очевидно, відображає шаблон #loading, поки асинхронізація очікує даних. Якщо спостережуване повертає дані, воно перебирає значення каталогу.

Але зараз я хочу розділити це на таку поведінку:

  • поки ми чекаємо даних, відобразимо анімацію завантаження
  • якщо ми отримали відповідь служби, а повернутий список порожній, покажіть інформаційний текст (наприклад, "ваш каталог порожній") і не повторюйте (оскільки даних немає)
  • якщо ми отримали відповідь служби, а повернутий список має значення, повторіть елементи (як у поточному стані)

Як я можу це отримати? З того, що я читав у схожих дописах, цього ніхто не намагався досягти (або я його не знайшов).

Дуже дякую!

Відповіді:

12 для відповіді № 1
 <div *ngIf="catalog$ | async as catalog; else loading">
<ng-container *ngIf="catalog.length; else noItems">
<div *ngFor="let item of catalog">{{item.title}}</div>
<ng-container>
<ng-template #noItems>No Items!</ng-template>
</div>
<ng-template #loading>loading animation...</ng-template>

Це повинно зробити трюк. Краще використовувати якомога менше асинхронних каналів і просто оголосити це "як" змінною шаблону, яку можна використовувати де завгодно. В іншому випадку потік буде виконуватися один раз за асинхронний канал, що є поганою практикою і може створити непотрібні виклики http, якщо це підтримується http.


0 для відповіді № 2

хммм .. https://github.com/angular/angular/issues/14479

Просто додайте ще один стан ngIf - else.

<div *ngIf="(catalog$ | async);  else loading;">
<div *ngIf="catalog$.length == 0; else empty;">
<ng-container *ngFor="let item of catalog$ | async">
<div>{{item.title}}</div>
<ng-container>
</div>
<ng-template #empty>empty animation...</ng-template>
</div>
<ng-template #loading>loading animation...</ng-template>