在Ngfor内部可观察到

时间:2019-06-13 23:44:04

标签: angular firebase

我正在学习编程...

我正在使用angularfire2(firebase)建立某种论坛,我有2个服务,一个服务管理所有用户配置文件数据,另一个管理消息。使用* ngfor,我显示所有消息(在组件中调用服务的功能)。消息接口具有提交消息的用户的uid。有了这个uid,我想获得例如在消息中显示的用户个人资料图片。

问题是,当我调用该函数时,我在一个可观察对象内部得到一个可观察对象,并且我的应用开始起泡。我做错了什么?

谢谢!

admin.requests.component.html。

    <div *ngFor="let request of requests" class="card shadow">



    ..img  ... src="{{getUserProfilePicture(request.clientId)}}" ... ">

getUserProfilePicture(uid)返回DOC的imgURL的值,其中uid = clientId

1 个答案:

答案 0 :(得分:1)

您正在寻找async pipe

  

异步管道订阅Observable或Promise并返回   它发出的最新值。发出新值时,异步   管道标记要检查更改的组件。当组件   被销毁后,异步管道会自动退订以避免   潜在的内存泄漏。

因此,如果您的可观察对象返回带有图像src的字符串,则重构后的代码可能类似于:

    ..img  ... src="{{getUserProfilePicture(request.clientId) | async}}" ... ">

我在ngFor循环中创建了一个working example of the async pipe供参考。

使用异步管道需要注意一些潜在的事情:每次使用相同的可观察对象时,除非您使用as语法捕获值,否则它将再次订阅可观察对象。这意味着什么:例如,如果您有一个异步管道调用Web服务,那么您将被多次调用:

<!-- Async pipe subscribes once... -->
<img src="{{someHttpCall(request.clientId) | async}}"/>
<!-- Async pipe subscribes again... -->
<p>Img loaded from: {{someHttpCall(request.clientId) | async}}</p>

如果您希望将以上as语法重构给我们,以捕获输出并避免多次服务器调用,则如下所示:

<!-- Capture our observable to prevent subsequent subscriptions. 
     Async pipe only subscribes once. -->
<ng-container *ngIf="someHttpCall(request.clientId) | async as imgSrc">
   <img src="{{ imgSrc }}"/>
   <!-- Also note we don't need the async pipe because it already subscribed 
        to the observable for us and we captured the value in our template -->
   <p>Img loaded from: {{ imgSrc }}</p>
</ng-container>

无论如何,这是很多新的Angular开发人员都陷入的陷阱,所以我认为在没有一点警告的情况下,我不会引入async管道。