提问者:小点点

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


一直在尝试将两个可观察对象组合成一个*ngIF,并在两者都发出时显示用户交互界面。

采取:

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

来自:将两个异步订阅放在一个Angular*ngIF语句中

这就像它编译一样,但是在我的例子中语言$用户$将来自两个HTTP请求,并且似乎用户$抛出运行时错误,例如TypeError:_v. context.ngIf.user是未定义的

本质上我真正想要的是(这行不通):

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

是最好的解决方案:

  • 在组件内部订阅并写入变量
  • 将组件内的两个可观察对象与saywith LatestFrom
  • 结合起来
  • 添加空检查{{userLanguage?. user}}

共3个答案

匿名用户

此条件应使用嵌套的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请求将被串联执行。

为了同时执行它们并且仍然拥有语言用户变量,需要更多嵌套:

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

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

匿名用户

您也可以使用以下技巧。您将需要一个额外的嵌套。

<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命名你的变量。

匿名用户

这取决于你想要什么,但我认为带有加载标志的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中并显示它。

相关问题