1

从我在网上找到的内容来看,我认为目前无法使用 foreach 数据绑定来遍历淘汰赛中可观察对象的属性。

如果有人可以帮助我解决我正在尝试做的事情,我将非常感激。

假设我有一系列电影对象:

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);
}

我已经尝试了大约十几种其他解决方案,我开始怀疑这是否是我缺乏淘汰赛的知识(我仍然很绿色),或者这不可能是我想要的方式.

4

1 回答 1

0

您可以将数组“movies”设为 KO 可观察数组,将数组“movieGenre”设为 KO 计算属性。看看这个小提琴

为了方便读者,下面给出了小提琴中的代码;

KO 查看模型

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”是一个计算属性。每当可观察数组“movies”发生变化时,都会计算并缓存 moveGenre。但是,由于 this 未声明为可写计算属性,因此您无法将其绑定到您的视图。因此,它的值用于数据绑定。

渲染的方法是简单地循环计算“movieGenre”,并为电影嵌套另一个循环。在向表中添加一行之前,对于相应的表,电影对象使用当前的电影流派进行评估。在这里,使用了无容器控制流语法。我们可以使用“if”绑定,但这会为每个电影对象留下一个空的表行,其中流派是其他类型。

$parent 绑定上下文用于访问嵌套循环中的父上下文。

希望这可以帮助。

于 2013-03-25T19:11:39.110 回答