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

Phi*_*hil 22 angular

试图将两个observable组合成一个,*ngIf并在两者都发出时显示用户界面.

采取:

<div *ngIf="{ language: language$ | async, user: user$ | async } as userLanguage">
    <b>{{userLanguage.language}}</b> and <b>{{userLanguage.user}}</b>
</div>
Run Code Online (Sandbox Code Playgroud)

From:在一个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>
Run Code Online (Sandbox Code Playgroud)

是最好的解决方案:

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

Est*_*ask 52

应使用嵌套ngIf指令处理此条件:

<ng-container *ngIf="language$ | async as language">
  <div *ngIf="user$ | async as user">
    <b>{{language}}</b> and <b>{{user}}</b>
  </div>
<ng-container>
Run Code Online (Sandbox Code Playgroud)

缺点是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>
Run Code Online (Sandbox Code Playgroud)

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

  • 这个答案的最后一句话就是答案!在组件类中创建一个可观察的对象,而不是嵌套的对象! (2认同)
  • 如果您只想在模板中使用“组合可观察量”,那么当对象语法易于阅读和理解并且位于使用它的同一位置时,为什么要在类中直接写出来呢?我只需去掉两个内部的“ng-container”,并直接在模板中引用“obj.user”/“obj.language”。 (2认同)

wes*_*tor 21

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

<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>
Run Code Online (Sandbox Code Playgroud)

对象 o 始终为真,因此第一个 *ngIf 简单地用于保存流值。在里面你必须用 o 命名你的变量。

  • 我喜欢这是一个选项,但实际上,这与 myStreams$=combineLatest([stream$1,stream2$,stream3$], (a, b, c,) =&gt; ({a, b, c} )).pipe( 过滤器((c) =&gt; Object.values(c).every((v) =&gt; v != null)) ); 然后 &lt;ng-container *ngIf="myStreams$ | async; let o;"&gt;...&lt;/ng-container&gt; (3认同)
  • 太棒了,之前没有见过外部 `ngIf` 对象方法 (2认同)
  • @chrismarx 这将是一个更好的方法 - 但模板解决方案也很有趣 (2认同)

mic*_*elw 5

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

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

forkJoin等待所有Observable完成返回其订阅中的值

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

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

  • 应该注意的是,forkJoin 仅适用于已完成的可观察量(即 Http 可观察量)。 (3认同)
  • @estus是的,这就是我写的原因,这取决于你想要什么:) (2认同)