我正在使用knockout映射插件将计算属性添加到可观察数组中的项目。但是,此计算属性依赖于我的viewmodel中的不同属性。
在映射期间创建observable时如何访问viewmodel属性?
请注意,我无法使用options.parent,因为该属性在viewModel中更进一步。
我也无法更改viewmodel,因为它是生成服务器端的。
编辑:
这是一个显示问题的JSFiddle。注释掉的那条线是我需要工作的。
这就是我现在所拥有的,但显然是一个错误:
var mapping = {
'Collection': {
create: function(options) {
var model = ko.mapping.fromJS(options.data);
model.Total = ko.computed(function() {
var result = this.Price() * viewModel.Count(); // :(
return result;
}, model);
return model;
}
}
};
var json = { ... large json object ... };
var viewModel = ko.mapping.fromJS(json, mapping);
答案 0 :(得分:1)
一种可能的解决方案是使用{deferEvaluation: true}
选项。因此,只有在viewModel
准备好并且实际使用了Total
属性时才会计算您的计算函数:
var mapping = {
'Collection': {
create: function(options) {
var model = ko.mapping.fromJS(options.data);
model.Total = ko.computed(function() {
var result = this.Price() * viewModel.Count();
return result;
}, model, {deferEvaluation: true});
return model;
}
}
};
演示JSFiddle。
但是,使用此方法,您可以将视图模型名称与映射选项紧密耦合。因为如果您更改var viewModel = ko.mapping.fromJS(json, mapping);
并以不同方式命名viewModel
,那么您还必须更新映射配置。
因为没有办法走'父母'#34;映射配置中的链可能对于这种情况,映射插件不是最好的解决方案......
这是一种使用手写视图模型并传递" root"的另一种方法。它需要在哪里:
var MainViewModel = function (json) {
ko.mapping.fromJS(json, { 'ignore': ["Foo"] }, this); //map the rest
this.Foo = new FooViewModel(json.Foo, this);
}
var FooViewModel = function (json, root) {
ko.mapping.fromJS(json, { 'ignore': ["Bar"] }, this); //map the rest
this.Bar = new BarViewModel(json.Bar, root);
}
var BarViewModel = function (json, root) {
ko.mapping.fromJS(json, { 'ignore': ["Collection"] }, this); //map the rest
this.Collection = ko.mapping.fromJS(json.Collection, {
create: function(options) {
var model = ko.mapping.fromJS(options.data);
model.Total = ko.computed(function() {
var result = this.Price() * root.Count();
return result;
}, model);
return model;
}});
}
演示JSFiddle。
答案 1 :(得分:1)
使用映射插件,可以从多个源映射。我想你可以做到
var viewModel = ko.mapping.fromJS(json);
viewModel = ko.mapping.fromJS(json, mapping, viewModel),
在第一次映射之后,您将每个Price作为一个可观察的集合。在第二次映射之后,您将拥有Total以及可观察的。