将计算属性添加到视图模型及其子项

时间:2016-03-05 21:40:14

标签: knockout.js knockout-mapping-plugin

我想尝试简要说明一下我遇到的问题。我认为我非常接近解决方案,但我需要你的帮助才能完成。

让我们说我有一个看起来像这样的视图模型:

function viewModel(){
    var self = this;
    self.foo = ko.observable();
    self.bars = ko.observableArray();
}

function bar(data){
    var self = this;
    self.baz = ko.observable();
    ko.mapping.fromJS(data, mapperSettings, self);
}

我使用ko.mapping plugin映射服务器中的一些数据:

var mapperSettings = {
     bars: {
        create: function(options) {
            return new bar(options.data);
        }
    }
};    

var dummyData = {
    foo: '1',
    bars: [{ baz: 1 }, { baz: 2 }]
};

var vm = new viewModel();
ko.mapping.fromJS(dummyData, mapperSettings, vm);

到目前为止一切都很好。

现在,我想用一些额外的计算属性来扩展视图模型及其项目。我已成功将其添加到视图模型中(something_computed下方),但我无法将计算属性添加到列表项 - computed属性{ {1}}项目如下:

bar

Fiddle

1 个答案:

答案 0 :(得分:1)

我已经调整了你的小提琴并让它工作,因为我认为你想要它 - 它在这里:

https://jsfiddle.net/4s6jsLx1/10/

我做的主要是实现下面描述的模式,以便您可以轻松,干净地定义每个带有计算结果的嵌套视图模型,而不会将代码绑定在结中(请参阅底部关于创建被调用的注释) 4次) -

首先,创建一些虚拟数据,例如

data = {foo: 1}

然后,为将保存此虚拟数据的视图模型创建视图模型定义。在这里定义你的计算。您通常不需要为foo定义一个observable,因为映射插件会为您创建,但因为您从计算中引用它,那么在这种情况下,您需要定义它:

function viewModel() {
    var self = this
    self.foo = ko.observable()
    self.computed_foo = ko.computed(function() {
        return self.foo() + " comp"
    })
}

然后将其实例化为空白视图模型,以获取具有计算结果的实例:

blank_vm = new viewModel()

最后,使用ko.mapping将数据填入其中。此示例提供{}作为空白设置对象,但在小提琴中我使用正确的设置对象来创建条形图:

vm = ko.mapping.fromJS(data, {}, blank_vm)

vm现在有两个属性,foo(其中foo() == 1)和computed_foo(其中computed_foo() == "1_comp"

关于创建被调用4次,如果用以下内容替换console.log:

console.log('create', options.data);

然后你将在第3次和第4次调用时看到,传入的数据是垃圾。我并没有花太多时间精确地确定它来自哪里,但从广义上讲,我认为你的代码在映射和计算机的交互方式方面有点紧密相关。我的解决方案完全按照上面概述的模式删除了这个创建方法,该模式旨在使计算的创建与映射过程分开。希望它能满足您的需求!