基于可见/现有元素的淘汰foreach索引

时间:2017-03-23 17:00:12

标签: knockout.js foreach

我有以JSON格式提供的数据并映射到KO observable,数据结构如下:

<div data-bind="foreach: list">
    <!-- ko if: ItemPhotos -->
        <!-- ko foreach: ItemPhotos -->
            <img data-bind="attr: { src: $data}"/>
        <!-- /ko -->
    <!-- /ko -->
</div>    

然后在我的代码中我想显示所有的ItemPhotos,所以我像这样循环:

bool is_prime(int n)
{
  if (n == 2) return true;
  if (n == 1 || n % 2 == 0) return false;

  for (int i = 3; i*i < n+1; i += 2) {
      if (n % i == 0) return false;
  }

  return true;
}

现在这个工作正常,只显示所有图像。但是,我想限制它只显示前5个图像(总计,而不是每个项目)。我也想要设置第一个图像的样式(首先是所有图像中的第一个图像,而不是每个图像中的第一个图像。

所以我认为可行的只是检查$ index,但如果我将索引放在“ItemPhotos”foreach中,那么它将为每个项目设置第一张照片的样式,每个项目最多只能拍摄5张照片(无限制)项目)。如果我检查了“list”foreach中的索引,我会设置所有第一项照片的样式,并且只允许5个项目,无论他们有多少张照片。事实上,有些项目没有照片,这就更难了。

无论如何在我的绑定中没有更改我的数据结构时进行这些检查,因为我在页面的下方使用了这个结构中的数据?

2 个答案:

答案 0 :(得分:3)

在viewmodel中进行数据操作,而不是在视图中。计算可以给你你想要的东西。

const vm = {
  list: ko.observableArray([{
      ItemNumber: 1,
      ItemPhotos: null
    },
    {
      ItemNumber: 2,
      ItemPhotos: ["2Photo1Url", '2Photo2Url', '2Photo3Url']
    },
    {
      ItemNumber: 3,
      ItemPhotos: ["3Photo1Url", '3Photo2Url']
    },
    {
      ItemNumber: 4,
      ItemPhotos: ["4Photo1Url", '4Photo2Url']
    }
  ])
};

vm.firstFive = ko.computed(() => {
  const result = vm.list().reduce((a, b) => a.concat(b.ItemPhotos || []), []).slice(0,5);

  console.log(result);
  return result;
});

ko.applyBindings(vm);
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="foreach: firstFive">
  <img data-bind="attr: { src: $data}" />
  <div data-bind="text: $data"></div>
</div>

答案 1 :(得分:1)

您可以引入GetItemPhotos()方法,在达到限制时返回空数组:

var photosCounter = 0,
    maxPhotosToReturn = 5;

yourViewModel.GetItemPhotosFor = function(item) {
    if (!item.ItemPhotos || photosCounter >= maxPhotosToReturn) return [];

    var photos = item.ItemPhotos.slice(0, maxPhotosToReturn - photosCounter);
    photosCounter += photos.length;

    return photos;
};

在你的HTML中:

<!-- ko foreach: $root.GetItemPhotosFor($data) -->
    <img data-bind="attr: { src: $data }"/>
<!-- /ko -->