我有以下型号:
var model = {
A: 'One',
B: 'Two',
C: 'Three'
};
我将各种UI元素绑定到这些字段,效果很好。但是,我将模型转换回JavaScript对象,以便我可以保存对服务器的任何更改:
var goingToServer = ko.toJS(model);
goingToServer
将包含属性A,B和C.但是,假设属性C是一大块数据,永远不会改变。我想避免将其发送回服务器。
在将模型转换回JavaScript对象时,是否有办法让toJS()
包含一组预定义的字段?
我一直在研究的一件事是Knockout Mapping plugin。它有一个名为 include 的设置,其记录如下:
将视图模型转换回JS对象时,默认情况下为 映射插件只包含属于您的属性 原始视图模型,除了它还将包括 Knockout生成的_destroy属性,即使它不是你的一部分 原始物体。但是,您可以选择自定义此阵列:
但是,看起来此插件无法正常工作,因为ko.mapping.toJS()
仍将包含A,B和C,即使我传入include
数组['A', 'B']
也是如此。我猜这个功能旨在包含其他字段,这些字段不在原始模型中。
有没有办法在将模型转换回JavaScript对象时排除某些属性,而不是做一些hacky,例如生成对象并在发送到服务器之前手动删除我不想要的属性?
答案 0 :(得分:24)
您是否尝试过ignore
关键字?它与include的用法类似:
var mapping = {
'ignore': ["propertyToIgnore", "alsoIgnoreThis"]
}
var viewModel = ko.mapping.toJS(data, mapping);
当您执行服务器数据的原始映射时,您可以使用ignore,然后当您将其转换回JS时,它根本不会出现在您的对象上。
答案 1 :(得分:3)
如果我们在vm.Payment observable reference下有一个复杂的对象模型实例:
{
"Summary": {
"Count": 12,
"PaymentAmount": 1500,
"PaymentMethod": "Cheque",
"PaymentDate": "2015-04-08T22:38:48.552Z",
"AgentOid": 1208795,
"AgentName": "Asere Ware"
}
//[...]
}

并且只需忽略一些内部属性,然后:
var mapping = {
'ignore': ['Summary.PaymentMethod', 'Summary.PaymentDate'] //avoid lost some initialized values.
};
// map updating existing observable (Payment) under my ViewMode (vm) with source "data" JSON object.
ko.mapping.fromJS(data, mapping, vm.Payment);

这是vm.Payment内容的结果,其中只有PaymentMethod和PaymentDate保持不变:
{
"Summary": {
"Count": 0,
"PaymentAmount": 0,
"PaymentMethod": "Cheque",
"PaymentDate": "2015-04-08T22:38:48.552Z",
"AgentOid": undefined,
"AgentName": undefined
}
//[...]
}

答案 2 :(得分:2)
好的,我已经找到了一个有效的解决方案,虽然我希望有更好的方法。诀窍是忽略映射插件中的这些字段,然后手动将它们作为计算字段添加。在调用toJS
时,计算字段永远不会在生成的JavaScript对象中结束。
// Utility function to quickly generate a computed field
ko.readonly = function (value)
{
return ko.computed(function ()
{
return value;
});
};
// View Model
var ViewModel = function (project)
{
var readonly = ['B', 'C', 'D']; // Fields I want to ignore
var mapping = {
'ignore': readonly //Read-only properties, we'll add these manually as computed fields
};
// Use Mapping plugin to make everything observable, except the fields above
ko.mapping.fromJS(project, mapping, this);
// Now loop through the read only array and add these fields in as computed
for(var i = 0; i < readonly.length; i++)
{
var field = readonly[i];
this[field] = ko.readonly(project[field]);
}
}
我现在可以正常绑定到这些视图模型:
ko.applyBindings(new ViewModel(data));