将Observable最佳地绑定到* ngFor内的元素attr.src

时间:2018-03-15 14:36:50

标签: angular

我有一个Angular组件,可以有效地显示视频流列表的缩略图列表:

<div *ngFor="let s of streamList;trackBy: streamListTrackFn">
  <div class="thumbnail">
    <img [attr.src]="loadThumbnail(s.thumbnailUrl) | async" />
   </div>
</div>

之前我直接绑定[src]="{{s.thumbnailUrl}}"并且随着streamList定期更新,我得到了一个用新缩略图渲染的新图像列表。

提供缩略图的服务需要基本身份验证,因此我尝试切换到使用我自己的XHR请求加载图像,这就是为什么我更改为[attr.src]="loadThumbnail(..)",它返回异步加载的图像数据URI作为`Ob​​servable ”

我的问题是,在网络选项卡上,即使streamList上没有发生任何变化,也会导致*ngFor我看到大量的HTTP请求被枪杀并被取消。我认为这是Angular中的摘要周期/绑定事物。

在这种情况下加载缩略图的最佳方法是什么,而不会陷入这种一遍又一遍地请求缩略图的无限循环? (thumbnailUrl本身带有?t=123456计数器,以帮助缓解任何缓存问题)

loadThumbnail真正更改之前,如何阻止Angular执行新的streamList?或者实际上至少是s.thumbnailUrl

谢谢!

1 个答案:

答案 0 :(得分:0)

嗯,首先,在模板绑定中使用这种函数绝对是错误的。虽然角度刷新了html绑定,但它会对它们进行数十万次的评估,因此这些函数必须非常快速,而且它们肯定不能在Web上获取一些外部资源。他们使用的所有东西必须立即可用。

我的猜测是你只需要将attr.src属性直接绑定到s.thumbnailUrl(顺便说一下,loadThumbnail()函数做什么?),但是没有看到这个组件周围的所有代码 - 猜测是我能做的最好。

<强>更新

我建议更改loadThumbnail()以便它返回图片数据而不是网址(例如,请参阅here),在{{1}的同一位置调用它分配/更新,并绑定到包含该数据的对象字段 - 类似于下面的代码。无论如何,它并没有改变答案的其余部分 - html绑定仍然是错误的地方,所有这一切。 :)

streamList gets

然后将其绑定在模板中,如下所示:

// this is something like you probably have
this.someService.getStreamList().subscribe((sl) => {
    this.streamList = sl;

    // this is not elegant at all and can be done better for sure
    // but will do just to convey the idea
    Observable.fromArray(this.streamList).subscribe((s) => {
        this.loadThumbnail(s.thumbnailUrl).subscribe((data) => {
            s.thumbnail = data;
        });
    });
});