我有一个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();
}
}
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模板。如果observable返回数据,它将遍历目录值。
但现在我想把它分成这种行为:
我怎么能做到这一点?从我在类似帖子上看到的,没有人试图实现这一点(或者我没有找到它)。
非常感谢!
答案 0 :(得分:36)
<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>
这应该可以解决问题。最好尽可能少地使用同步管道并将其声明为#34; as&#34;您可以在任何地方使用的模板变量。否则,每个异步管道将执行一次流,这是一种不好的做法,如果这是http支持,可能会创建不需要的http调用。
*编辑语法错误
答案 1 :(得分:1)
嗯.. 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>