5

我一直在研究动态数据绑定的淘汰赛,并且我遇到了需要一个可观察数组来包含多个可观察对象的情况。

这是我的代码:

<ul data-bind="foreach: { data: categories, as: 'category' }">
    <li>
        <ul data-bind="foreach: { data: items, as: 'item' }">
            <li>
                <span data-bind="text: category.name"></span>:
                <span data-bind="text: item"></span>
                <input type="text" data-bind="value: item"/>
            </li>
        </ul>
    </li>
</ul>

$(document).ready(function () {
            ko.applyBindings(viewModel);
        });

        var viewModel = {
            categories: ko.observableArray([
                { name: 'Fruit', items: [ko.observable('Apple'), ko.observable('Orange'), ko.observable('Banana')] },
                { name: 'Vegetables', items: [ko.observable('Celery'), ko.observable('Corn'), ko.observable('Spinach')] }
            ])
        };

使用 oject observables 时,通常我可以修改输入文本框的值,并将该值设置为用于显示该属性的整个页面。

在我当前的示例中,我尝试对我的输入框做同样的事情,但是在我修改了文本框中的值之后,跨度没有达到当前值。

如果它们是独立的可观察对象,如何使 observableArray 中的可观察对象表现得像它们一样?

4

2 回答 2

1

当我遇到这些问题时,我喜欢将它们分解为子虚拟机,这样我可以更好地控制我所在的每个上下文级别发生的事情。对于上述问题,我会做这样的事情:

var produceVM = function (data) {
    var self = this;

    self.item = ko.observable(data);
}

var categoryVM = function (data) {
    var self = this;

    self.name = ko.observable(data.name);
    self.items = ko.observableArray();

    var items = ko.utils.arrayMap(data.items, function (item) {
        return new produceVM(item);
    });

    self.items(items);
}

var viewModel = function (data) {
    var self = this;

    self.categories = ko.observableArray();

    var categories = ko.utils.arrayMap(data, function (category) {
       return new categoryVM(category); 
    });

    self.categories(categories);
}

var data = [
    { name: 'Fruit', items: [ 'Apple', 'Orange', 'Banana' ] },
    { name: 'Vegetables', items: ['Celery', 'Corn', 'Spinach' ]}
];

ko.applyBindings(new viewModel(data));

我相信 ko 映射插件可以实现与此类似的功能,而无需编写上述所有代码。您可以将数据模型传递给它,它会为每个项目构建可观察对象。

于 2013-05-25T23:18:44.847 回答
0

正如@nemesv指出的那样,答案就在拐角处。

只需将每个数组项包装到对象中,它就会完美地工作。

这就是您的视图模型的外观,这是一个有效的jsfiddle

var viewModel = {
    categories: ko.observableArray([{
        name: 'Fruit',
        items: [
            {name: ko.observable('Apple')},
            {name: ko.observable('Orange')},
            {name: ko.observable('Banana')}
        ]
    }, {
        name: 'Vegetables',
        items: [
            {name: ko.observable('Celery')},
            {name: ko.observable('Corn')},
            {name: ko.observable('Spinach')}
        ]
    }])
};

我不得不根据我自己的经验说,通常无论如何你都会在数组中拥有对象,而不是声称没有其他用例,只是说在数组中拥有对象并能够动态更改它们非常有用而不必担心其他任何事情。

于 2013-05-25T23:14:20.707 回答