将计算的observable添加到数组中的项目

时间:2012-08-27 19:41:49

标签: knockout.js

在KnockoutJS中,我尝试将计算的observable添加到数组的每个项目中:

for (var i = 0; i < items().length; i++) {
    var item = items()[i];
    item.valid = ko.computed(function() {
        var valid = true;
        valid = valid && item.firstName() && item.firstName().length > 0;
        valid = valid && item.lastName() && item.lastName().length > 0;
        return valid;
    });
}

这始终更新valid()的所有出现,并且它仅适用于数组的最后一项。

我认为这是一种背景问题,但我不明白。

完整的代码可以在this jsfiddle

中找到

更新

我找到了一个基于映射选项here的解决方案。

可以找到基于解决方案的jsfiddle here

唉,这需要从AJAX中针对不同数据(无论是否需要有效属性)不同地调用映射。

映射完成后有没有办法可以使用?

1 个答案:

答案 0 :(得分:0)

我更新了你的小提琴,以显示一个更明确的例子:

http://jsfiddle.net/JasonMore/s9Rmp/2/

这是我现在用于映射的实时代码片段。它可能会帮助你前进。 DisplayViewModel是最终被绑定的父视图模型。

// helpers

var dateConvert = {
    create: function (options) {
        return new Date(parseInt(options.data.substr(6)));
    }
};

var viewModelConvert = function (viewModelType) {
    return {
        create: function (options) {
            return new viewModelType(options.data);
        }
    }
};

// View Models

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

    ko.mapping.fromJS(data, {}, this);

    this.ShowText = ko.computed(function () {
        var val = self.ValueType();
        return val !== contentType.Image && val !== contentType.Html;
    });

};

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

    ko.mapping.fromJS(data,
        {
            'Layouts': viewModelConvert(layoutViewModel)
        }, this);
};

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

    // Mapping
    ko.mapping.fromJS(data,
        {
            'Zones': viewModelConvert(zoneViewModel)
        }, this);
};

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

    ko.mapping.fromJS(data,
        {
            'Presentations': viewModelConvert(presentationViewModel),
            'EndDateTime': dateConvert,
            'StartDateTime': dateConvert
        }, this);
};

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

    ko.mapping.fromJS(data, {}, this);

    this.fontFace = ko.computed(function () {
        return "@font-face {font-family: '" + self.Name() + "'; src:url('" + settings.fontUrl + self.FileName() + "')}";
    });
};

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

    this.init = function () {

    };

    ko.mapping.fromJS(data,
        {
            'Events': viewModelConvert(eventViewModel),
            'Fonts': viewModelConvert(fontViewModel)
        }, this);
};