使用knockout逐步加载视频元数据数组

时间:2017-07-28 01:04:49

标签: javascript html video knockout.js

我的页面需要显示 n 视频预览的网格。浏览器与任何给定域只能有〜5-6个活动连接。防止"等待套接字连接......"问题,我试图逐步加载视频元数据。

我有以下内容:

 <!-- ko foreach: videos() -->
  <video data-bind="attr: {src: mediaPath, preload: $parent.preloadCount() > $index() ? 'metadata' : 'none'}, event: {loadedmetadata: $parent.incrementPreloadCount}"></video>
 <!--/ko-->

在我的viewmodel中:

    vm.preloadCount = ko.observable(4);
    vm.incrementPreloadCount = function () {
        feedVm.preloadCount(feedVm.preloadCount() + 1);
    };

我们的想法是,每次加载视频的元数据时,loadedmetadata事件都会触发逐步将none切换为metadata的增量。

问题在于,我的videos会在每次增量时重新评估,每次src更新时都会重新preloadCount

如何防止之前&#34;切换&#34;视频被重新评估?我可以在这里使用一个相对简单的JS解决方案,但如果可以,我想利用淘汰赛。

1 个答案:

答案 0 :(得分:2)

map为其函数提供第二个参数,该参数是正在操作的元素的索引。您可以将其用作计算中$index的替代,以返回数组的映射。

使用计算器来处理preload属性值应该不会触及您的视频元素,除非计算出的值发生变化。

const vm = {
  arr: ['one', 'two', 'three', 'four', 'five'],
  preloadCount: ko.observable(0)
};

vm.videos = ko.computed(() => vm.arr.map((v, i) => ({
  v,
  i,
  preload: ko.computed(() => vm.preloadCount() > i ? 'metadata' : 'none')
})));

ko.applyBindings(vm);

setInterval(() => vm.preloadCount(1 + vm.preloadCount()), 1200);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="foreach: videos">
  <div>
    <span data-bind="text: i"></span>
    <span data-bind="text: v"></span>
    <span data-bind="text: preload"></span>
  </div>
</div>