observableArray中的可观察对象不会自动更新

时间:2013-05-22 14:43:02

标签: javascript knockout.js

我一直在寻找动态数据绑定的Knockout,我有一种情况需要一个可观察的数组来包含多个可观察对象。

这是我的代码:

<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 observable时,我通常可以修改输入文本框的值,并将该值设置为用于显示该属性的整个页面。

在我当前的例子中,我尝试对输入框执行相同的操作,但在修改了文本框中的值后,范围没有达到当前值。

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

2 个答案:

答案 0 :(得分:1)

当我遇到这些问题时,我喜欢将它们分解为子vms,这使我能够更好地控制上下文中每个级别的内容。对于上述问题,我会做这样的事情:< / p>

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映射插件可以实现与此类似的功能,而无需编写上述所有代码。您可以将数据模型传递给它,并为每个项目构建observable。

答案 1 :(得分: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')}
        ]
    }])
};

我必须从我自己的经验中说,通常你会在数组中包含对象,而不是声称没有其他用例,只是说在数组中有对象并且有能力动态地改变它们而不用担心其他任何事情。