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

Posted

技术标签:

【中文标题】将两个异步订阅放在一个 Angular *ngIf 语句中【英文标题】:Putting two async subscriptions in one Angular *ngIf statement 【发布时间】:2017-12-04 22:52:43 【问题描述】:

我的组件模板中有以下内容:

<div *ngIf="user$ | async as user>...</div>

在上面的div 中,我想使用异步管道只订阅另一个可观察对象一次,并在整个模板中像上面的user 一样使用它。例如,这样的事情是否可能:

<ng-template *ngIf="language$ | async as language>
<div *ngIf=" user$ | async as user>
  <p>All template code that would use both user and language would go in between</p>
  </div>
</ng-template>

或者这甚至可以组合在一个语句中?

【问题讨论】:

我想您是在问是否可以将“用户”作为新的模板变量引入,答案是否定的。异步管道只是将值作为表达式的一部分产生。您必须在要使用用户值的模板中的任何位置使用异步管道。 我需要的所有逻辑都在上面的div 中。因此,我不需要在其他任何地方重新引入 user 作为变量,因为我已经有了它。 请添加更多代码来解释您正在尝试做什么 plnkr.co/edit/xiOeJ5pbz2jmx8TIx4c0?p=preview 对,我唯一的问题是我使用*ngIf 来表示一个我知道存在的值,在这种情况下是可观察的语言。 【参考方案1】:

你可以使用对象作为变量:

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

Plunker Example

另见

How to declare a variable in a template in Angular2

【讨论】:

请再问一个问题:与您在 plunkr 中建议的那样添加额外的 ng-container 包装器相比,此方法是否存在性能障碍? &lt;ng-container *ngIf&gt;&lt;div&gt;&lt;/div&gt;&lt;/ng-container&gt;&lt;div *ngIf&gt;&lt;/div&gt; 之间没有太大区别,但 ng-container 会生成更多 Angular 应该处理的代码 @Sammy 如果元素上有多个结构指令,我们通常使用ng-container @Sammy 你可以在这里比较一下plnkr.co/edit/7Yd0IWEmMdQolKHf6bhw?p=preview 虽然这确实同时订阅了两个可观察对象,但该解决方案具有误导性,因为无论可观察对象的状态如何,结果对象总是真实的,例如 language: undefined, user: undefined 。使用 userLanguage.user.id 会导致错误。【参考方案2】:

使用“对象作为变量”的问题在于它与问题中的代码没有相同的行为(加上它是对 *ngIf 的轻度滥用,使其始终评估为真)。要获得所需的行为,您需要:

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

【讨论】:

【参考方案3】:

虽然其他解决方案有效,但它们稍微滥用了 ngIf 的目的,它应该只可选地呈现模板。我写了一个 ngxInit 指令,即使表达式结果是“假的”,它也会始终呈现。

<div *ngxInit=" language: language$ | async, user: user$ | async  as userLanguage">
   <!-- content -->
</div>

见https://github.com/amitport/ngx-init

【讨论】:

以上是关于将两个异步订阅放在一个 Angular *ngIf 语句中的主要内容,如果未能解决你的问题,请参考以下文章

如何在Angular 6中将异步管道的结果分配给没有*ngIf的变量

Ionic 4 Angular模板与异步管道绑定到可观察

Angular2 使用 *ngif 在 html 代码中设置类名

angular入门篇(2)——*ngIf,数据绑定事件,属性绑定

Angular 2订阅订阅另一个异步功能的服务

Angular 5. 检查子组件中的父 *ngIf