检查Observable是否未定义

时间:2019-11-02 19:44:26

标签: angular angular7

在Angular 7应用程序中,我具有以下模板:

<div *ngIf="avatarUrl$ | async;">
  <ng-container *ngIf="avatarUrl$ | async as avatarUrl">
    <img [src]="avatarUrl ? avatarUrl : 'avatar-default.png'">
  </ng-container>
</div>

avatarUrl$是可观察到的,就像通过服务从数据库获得的一样。

我只想在avatarUrl$加载值后才显示IMG。

但是,有时从服务获得的值是不确定的。

在这种情况下,我需要显示默认的头像,例如:avatar-default.png

问题是未定义avatar-default.png时未显示avatarUrl$

我认为是因为这种情况无法与未加载和正在加载但未定义的值区分开?

<div *ngIf="avatarUrl$ | async;">

我该如何解决?

3 个答案:

答案 0 :(得分:4)

似乎有点多余,您可以执行以下操作:

<div>
  <img [src]="(avatarUrl$ | async) || 'avatar-default.png'">
</div>

或更改组件中的可观察对象:

readonly avatarUrl$ = this.getAvatarFromSomeWhere().pipe(
  startWith('avatar-default.png')
);

<div>
  <img [src]="avatarUrl$ | async">
</div>

然后,您无需执行任何||,只需保持模板简单即可。只有当您确定请求最终会返回头像时,这种方式才有效

否则,您可以使用map对其进行扩展,以确保它总是返回一个值:

private readonly defaultAvatar = 'avatar-default.png';

readonly avatarUrl$ = this.getAvatarFromSomeWhere().pipe(
  map((avatar) => avatar || this.defaultAvatar),
  startWith(this.defaultAvatar)
);

修改

@C_Ogoo是正确的,我应该读得更好。

如果您只希望它在加载后才显示,则只需更改可观察对象:

readonly avatarUrl$ = this.getAvatarFromSomeWhere().pipe(
  map((avatar) => avatar || 'avatar-default.png')
);

,您可以像这样制作模板:

模板

<div *ngIf="avatarUrl$ | async as avatarUrl">
  <img [src]="avatarUrl">
</div>

答案 1 :(得分:2)

您可以使用可观察的对象来实现。当您希望不将null

中的观察值undefined0*ngIf阻塞时,此方法很有用
<div *ngIf="{url: avatarUrl$ | async} as data">
    <img [src]="data.url ? data.url : 'avatar-default.png'">
</div>

很高兴知道,如果需要,您可以在对象中包含多个可观察对象:

<div *ngIf="{url: avatarUrl$ | async, picture: pictureUrl$ | async} as data">
...
</div>

答案 2 :(得分:0)

Observable的第一个检查值是否未定义。

<ng-container *ngIf= avatarUrl$ === 'undefined' | async ; else loaded >
        <img [src]='avatar-default.png'>
</ng-container>
<ng-template #loaded >
    <div *ngIf="avatarUrl$ | async;">
          <img [src]="avatarUrl">
    </div>
</ng-template>