从我在网上找到的内容来看,我认为不可能使用foreach data-bind来遍历knockout中可观察对象的属性。
如果有人可以帮我解决我想要做的事情,我会非常感激。
假设我有一系列电影对象:
var movies = [{
title: 'My First Movie',
genre: 'comedy',
year: '1984'
},
{
title: 'My Next Movie',
genre: 'horror',
year: '1988'
},
];
我想要做的是在表格中显示这些数据,但每种类型的电影都有不同的表格。
所以我尝试过这样的事情:
<div data-bind="foreach: movieGenre">
<table>
<tr>
<td data-bind="year"></td>
<td data-bind="title"></td>
<td data-bind="genre"></td>
</tr>
</table>
</div>
我的数据源更改为:
for (var i = 0; i < movies.length; ++i) {
if (typeof moviesGenres[movies.genre] === 'undefined')
moviesGenres[movies.genre] = [];
moviesGenres[movies.genre].push(movie);
}
我已经尝试了十几个其他的解决方案,我开始怀疑这是否是我缺乏淘汰赛的知识(我还是很绿),或者说我不喜欢这样的方式它是。
答案 0 :(得分:0)
您可以使数组“movies”成为KO可观察数组,数组“movieGenre”成为KO计算属性。看看this fiddle。
为了方便读者,下面给出了小提琴中的代码;
KO View Model
function MoviesViewModel() {
var self = this;
self.movies = ko.observableArray([
{
title: 'My First Movie',
genre: 'comedy',
year: '1984'
},
{
title: 'My Next Movie',
genre: 'horror',
year: '1988'
},
{
title: 'My Other Movie',
genre: 'horror',
year: '1986'
}
]);
self.movieGenre = ko.computed(function() {
var genres = new Array();
var moviesArray = self.movies();
for (var i = 0; i < moviesArray.length; i++) {
if (genres.indexOf(moviesArray[i].genre) < 0) {
genres.push(moviesArray[i].genre);
}
}
return genres;
});
};
HTML
<div data-bind="foreach: movieGenre()">
<h3 data-bind="text: 'Genere : ' + $data"></h3>
<table border="solid">
<thead>
<tr>
<th>Title</th>
<th>Genre</th>
<th>Year</th>
</tr>
</thead>
<tbody data-bind="foreach: $parent.movies">
<!-- ko if: $data.genre === $parent -->
<tr>
<td data-bind="text: $data.title"></td>
<td data-bind="text: $data.genre"></td>
<td data-bind="text: $data.year"></td>
</tr>
<!-- /ko -->
</tbody>
</table>
</div>
正如您所看到的,“movieGenre”是一个计算属性。每当可观察数组“电影”发生变化时,就会计算并缓存moveGenre。但是,由于未将其声明为可写计算属性,因此无法将其绑定到视图。因此,它的值用于数据绑定。
渲染方法只是循环计算出的“movieGenre”,并为电影嵌套另一个循环。在向表中添加行之前,对于相应的表,将使用当前的movieGenre计算影片对象。这里,使用无容器控制流语法。我们可以使用“if”绑定,但是每个电影对象都会留下一个空表行,否则就会出现类型。
$ parent绑定上下文用于访问嵌套循环中的父上下文。
希望这有帮助。