我有一个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作为`Observable ”
我的问题是,在网络选项卡上,即使streamList
上没有发生任何变化,也会导致*ngFor
我看到大量的HTTP请求被枪杀并被取消。我认为这是Angular中的摘要周期/绑定事物。
在这种情况下加载缩略图的最佳方法是什么,而不会陷入这种一遍又一遍地请求缩略图的无限循环? (thumbnailUrl
本身带有?t=123456
计数器,以帮助缓解任何缓存问题)
在loadThumbnail
真正更改之前,如何阻止Angular执行新的streamList
?或者实际上至少是s.thumbnailUrl
?
谢谢!
答案 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;
});
});
});