我正在使用Knockout运行ASP.net MVC4应用程序。
我有一个发布我的Knockout表单的通用脚本。
我需要优化发送到服务器的数据,因为当我发布我的Knockout ViewModel时,所有项目的SelectList也会被发布!
示例服务器ViewModel:
Public Class FooViewModel
Public Property Bar As String
Public Property Products As List(Of SelectListItem)
End Class
将我的Knockout ViewModel转换为JSON的JS代码
var data = ko.toJSON(viewModel);
数据变量包含所有产品项目,并且不是很优化。
我找到了这段代码(有效):
viewModel.toJSON = function () {
var copy = ko.toJS(this);
// remove any unneeded properties
delete copy.Products;
return copy;
}
但我需要 通用 解决方案......!在这里,我不知道如何让它变得通用......
快速而肮脏的解决方案是在每个数组属性上添加后缀,例如" _NoPost"然后循环并删除具有此后缀的每个属性,但它闻起来......糟糕:/
有什么想法吗?
答案 0 :(得分:1)
一个选项是将表单数据与查找数据分开,如下所示。当您需要将表单数据发布到服务器时,这将允许您仅获取表单数据。
Public Class FormViewModel
Public Property Bar As String
End Class
Public Class FooViewModel
Public Property FormData As FormViewModel
Public Property Products As List(Of SelectListItem)
End Class
这将允许你
var data = ko.toJSON(viewModel);
$post(url, data.FormData, function(d){...});
在HTML中,您还必须将FormData作为变量的一部分包括在内。
<input data-bind="value: FormData.Bar">
修改强>
根据您的反馈,您可以使用以下函数为您构建“干净”对象。我们的想法是传入原始的JSON对象以及一个映射对象,该对象将指示应该排除/遗留哪些属性:
function MapJson(obj, map) {
if (obj == undefined)
return;
map = map || {};
var ret = {};
for (var prop in obj) {
if (map[prop] != undefined && map[prop] == false)
continue;
if (typeof obj[prop] !== "object")
ret[prop] = obj[prop];
else {
if (map.constructor == Array) {
ret[prop] = MapJson(obj[prop], map[0]);
}
else
ret[prop] = MapJson(obj[prop], map[prop]);
}
}
return ret;
}
然后您可以像这样使用它 - 通过将属性的值设置为 false ,它将从数据中排除。该示例演示如何阻止子对象中的数组以及数组中的数组:
var obj = {
Name: "John Doe",
Vehicle: {
Details: {
Make: "Mazda",
Model: 2010
},
Registration: "ABC123",
ServiceDates: ["01 Jan", "23 Feb", "13 March"]
},
WeekDays: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
Children: [{ Name: "Mary", Age: 4, Hobbies: ["Soccer", "Chess", "Swim"] }, { Name: "Jane", Age: 2, Hobbies: ["Tennis", "Movies", "Reading"] }]
};
var map = {
Vehicle: {
ServiceDates: false
},
Children: [{
Hobbies: false,
}]
};
MapJson(obj, map);
希望它有所帮助。
编辑2
此处提供了一份基于您在评论中发布的数据的工作示例。
var vm = {
"Type":"PropertyTax",
"Label":"d",
"StartDate":"2015-01-01T00:00:00",
"EndDate":"2015-12-31T00:00:00",
"Value":0,
"RegularizationMonth":0,
"TotalConsumption":null,
"UnitPrice":null,
"Active":true,"Products":[{"Selected":false,"Text":"XXX 39","Value":"28"},{"Selected":false,"Text":"ZZZ","Value":"38"}],"ChargeProducts":[{"ProductID":"28","Products":[{"Selected":false,"Text":"XXX 39","Value":"28"},{"Selected":false,"Text":"XXX 41","Value":"8"}]}],
"map":{"Products":false,"ChargeProducts":[{"Products":false}]}
};
var result = MapJson(vm, vm.map);
console.log("Result: ", result);
答案 1 :(得分:0)
如果您使用KO.Mapping,则可以选择要忽略的某些部分。
var mapping = { 'ignore': ["SomeFieldProperty"] };
ko.mapping.fromJS(data, mapping, viewModel);
文档中的这一部分列出了操作绑定的所有方法,用于ko.mapping:
http://knockoutjs.com/documentation/plugins-mapping.html
向下滚动到底部,查看ignore
上的位以及有关如何管理绑定和降级的主题。