Angular - 如何在html中使用async管道绑定observable<Object>到本地变量?

69

嗨,我有一个可观察的 user$ 对象,拥有许多属性(如名称、标题、地址...)

component{
  user$:Observerable<User>;
  constructor(private userService:UserService){
    this.user$ = this.userService.someMethodReturningObservable$()
  }
}

有没有办法在HTML模板中使用async管道来订阅它并将其绑定到本地变量,就像这样:

是否可以使用async管道在html模板中订阅并将其绑定到本地变量?

<div #user="user$ | async">
  <h3> {{user.name}}
</div>

我知道可以在构造函数中订阅它,然后在 OnLeave/OnDestroy 中取消订阅,但我只是好奇是否可以使用异步管道。

干杯


据我所知,异步管道只能与*ngFor一起使用?你可以这样做*ngFor="let u of (user = (user$ | async))",但似乎有些可疑。需要更实际的操作。 - Babar Hussain
不使用异步也可以在单个可观察对象上工作,详见 ngrx/store :) - Han Che
4个回答

154

#代表模板引用变量。它指向DOM元素,不能像这样使用。

截至目前,Angular没有实现局部变量,可以通过此已关闭问题来监视相关问题的参考资料。

自从Angular 4以后,ngIfngFor指令的语法已更新,以允许使用局部变量。有关详细信息,请参见ngIf文献。因此,是可能的。

<div *ngIf="user$ | async; let user">
  <h3> {{user.name}} </h3>
</div>

这将创建一个 div 包装元素,并为其提供隐蔽行为,因此不需要使用 ?. 'Elvis' 操作符。
如果不需要额外的标记,可以将其更改为
<ng-container *ngIf="user$ | async; let user">...</ng-container>

如果不希望使用隐蔽行为,可以将表达式更改为真实占位符值。
对于对象值,可以使用空对象作为占位符。
<div *ngIf="(user$ | async) || {}; let user">
  <h3> {{user?.name}} </h3>
</div>

或者作为原始值的空间。

<div *ngIf="(primitive$ | async) || ' '; let primitive">
  <h3> {{primitive}} </h3>
</div>

1
这对我来说是有效的,但是我收到了一个警告,说“应该是'of'”。我认为这是tslint的警告,但很难找到任何相关信息。 - Blexy
@Blexy 很难说这里出了什么问题,看起来像是某个消息的一部分。 - Estus Flask
1
是的,我也遇到了 'of' expected 的相同错误,我试图改写它,使得语法检查器和 Angular 都能理解,但这比预期的要困难一些。感觉好像需要使用 async 管道的自动魔法。 - Bjorn 'Bjeaurn' S
@Blexy,你没有提到这是IDE警告。事实上,TSLint不关心模板。 - Estus Flask
@Blexy 看看 Wooli Design 的回答,这是对我有用的。 关于你的 IDE 警告;如果你使用 ng cli,它确实会关心模板,并且如果发现不兼容性就会抛出错误。 - Bjorn 'Bjeaurn' S
显示剩余2条评论

43

@Bjorn Schijff和@estus

不要:

<div *ngIf="(user$ | async) || {}; let user">

做:

<div *ngIf="(user | async) as user">

是的,我有Angular 4.4.3。 - Wooli Design
2
框架支持aslet。为什么一定要这样做而不是其他方式呢? - Estus Flask
我不知道,它在Angular 4.4.3上运行正常。也许两者都适用于Angular 5。 - Wooli Design
@WooliDesign 给出的示例可行,这里是文档参考链接 - Vino
这样做会在Angular 8中导致未解决的变量错误。 - Wildhammer
如果用户未登录,则不会评估#2... 这是一个很大的区别。 - Jonathan

8
使用以下语法:
<div *ngIf="(user | async) as user"> 

注意:在表达式末尾添加“as user”。

这样做的作用是等待user$ | async评估完毕,然后将结果绑定到值为user(无美元后缀)的变量上。


4
这与@WooliDesign的回答有什么不同? - Jonathan Lam

1

对于 *ngFor,可以在父元素上添加 *ngIf 指令:

    <ul *ngIf="users$ | async as users">
      <li *ngFor="let user of users">{{user.name}}</li>
      <li *ngIf="!users.length">No users</li>
    </ul>

如果父元素已经有了结构性指令,那么引入一个中间元素,比如<ng-container>可能是必要的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接