我有以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个项目,无论他们有多少张照片。事实上,有些项目没有照片,这就更难了。
无论如何在我的绑定中没有更改我的数据结构时进行这些检查,因为我在页面的下方使用了这个结构中的数据?
答案 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 -->