【发布时间】:2017-04-19 04:12:12
【问题描述】:
我非常不需要为一组值重建 DOM,每个值都包含一个表示 YouTube 直播的对象。我正在使用 ngFor 来迭代直播。
但是,当直播发生变化时(这可能是因为用户想要改变观看顺序,所以他们最想观看的直播在顶部 - 参见下面的reorder()),ngFor 会重建元素,这会导致 YouTube 嵌入从 DOM 中移除并重新插入;这会导致正在运行的直播停止播放,并重新加载它们 - 这需要一秒钟左右的时间。这不是最佳选择。
我尝试使用trackBy 来跟随直播名称(我的对象中的一个属性)而不是对象本身的值,但这似乎没有解决问题。
模板:
<livestream-player *ngFor="let livestream of userPrefs.visibleLivestreams(); trackBy: livestreamTrackByFn" [video]="livestream.url | sanitize:'resource'">
</livestream-player>
元素数组:userPrefs.visibleLivestreams()
public visibleLivestreams() : Livestream[] {
let livestreams = [
{ name: 'a', url: 'youtubeUrl', ... },
{ name: 'b', url: 'youtubeUrl', ... },
{ name: 'c', url: 'youtubeUrl', ... }
];
// _visibleLivestreams, used below to order and filter,
// is a simple, ordered, array of strings representing
// the livestream names, stored in localstorage.
return livestreams
.filter(l => this._visibleLivestreams.indexOf(l.name) != -1);
.sort((a, b) => this._visibleLivestreams.indexOf(a.name) < this._visibleLivestreams.indexOf(b.name) ? -1 : 1);
}
*ngFor 模板中使用的 trackBy 功能无效
public livestreamTrackByFn(index: number, item: Livestream) : string {
return item.name;
}
重新排序功能
/**
* Reorders elements of the livestreams array by shifting off the
* 0th element, and pushing it the last position in the array.
*
* Calling this function results in the DOM being rebuilt!
*/
public rotate() : void {
// shift element off _visibleLivestreams
let elem = this.userPrefs.visibleLivestreams.shift();
// push element onto _visibleStreams
this.userPrefs.visibleLivestreams.push(elem);
}
由于上述实现不必要地重建 DOM,我真的在寻找解决这个问题的方法。到目前为止,我的想法是创建一个自定义的*ngFor-like 结构指令,使用 flexbox 来管理订单,或者只是在我现有的实现中确定一个小的更改来解决这个问题。
【问题讨论】:
标签: javascript angular ngfor