* 具有多个异步管道变量的 ngIf

尝试将两个可观测数据组合成一个 *ngIf,并在两个数据都发出时显示用户界面。

例如:

<div *ngIf="{ language: language$ | async, user: user$ | async } as userLanguage">
<b>{{userLanguage.language}}</b> and <b>{{userLanguage.user}}</b>
</div>

发信人: 将两个异步订阅放在一个 Angular * ngIf 语句中

在我的例子中,只要 language$user$来自两个 HTTP 请求,它就可以进行编译,而且 user$似乎抛出了类似于 TypeError: _v.context.ngIf.user is undefined的运行时错误。

本质上,我真正想要的是(这不管用) :

<div *ngIf="language$ | async as language && user$ | async as user">
<b>{{language}}</b> and <b>{{user}}</b>
</div>

是最好的解决办法:

  • 在组件内部订阅并写入变量
  • 将组件内部的两个可观测值与例如 withLatestFrom结合起来
  • 添加空检查 {{userLanguage?.user}}
46503 次浏览

这种情况应该使用嵌套的 ngIf指令来处理:

<ng-container *ngIf="language$ | async as language">
<div *ngIf="user$ | async as user">
<b>\{\{language}}</b> and <b>\{\{user}}</b>
</div>
<ng-container>

缺点是 HTTP 请求将以串行方式执行。

为了同时执行它们并保留 languageuser变量,需要进行更多的嵌套:

<ng-container *ngIf="{ language: language$ | async, user: user$ | async } as userLanguage">
<ng-container *ngIf="userLanguage.language as language">
<ng-container *ngIf="userLanguage.user as user">
<div><b>\{\{language}}</b> and <b>\{\{user}}</b></div>
</ng-container>
</ng-container>
</ng-container>

更有效的方法是在此时将逻辑从模板移动到组件类,并创建一个单一的可观察对象,例如使用 withLatestFrom

这取决于您想要什么,但是我认为带有加载标志的 forkJoin 操作符可能是一个好主意。

Https://www.learnrxjs.io/operators/combination/forkjoin.html

forkJoin 等待所有可观察数据完成以返回它们在订阅中的值

Observable.forkJoin(
Observable.of("my language").delay(1000),
Observable.of("my user").delay(1000),
).subscribe(results => {
this.language = results[0]
this.user = results[1]
})

您可以在订阅的 onError 中捕获错误并显示它。

您还可以使用以下技巧。

<ng-container *ngIf="{a: stream1$ | async, b: stream2$ | async, c: stream3$ | async} as o">
<ng-container *ngIf="o.a && o.b && o.c">
\{\{o.a}} \{\{o.b}} \{\{o.c}}
</ng-container>
</ng-container>

对象 o 永远是真实的,因此第一个 * ngIf 可以简单地用于保存流值。在里面,你必须用 o 来命名你的变量。