我在寻找解决类似问题时遇到了这篇文章,并认为我会为下一个人发布我的方法和解决方案。
我采用了您的思路-克隆对象并在“撤消”上使用旧数据重新填充:
1)将数据对象复制到新的页面变量(“_initData”)中 2)从原始服务器对象创建 Observable 3)在“撤消”时重新加载未更改数据的可观察对象(“_initData”)
简化的 JS:var _viewModel;var _initData = {};
$(function () {
//on initial load
$.post("/loadMeUp", {}, function (data) {
$.extend(_initData , data);
_viewModel = ko.mapping.fromJS(data);
});
//to rollback changes
$("#undo").live("click", function (){
var data = {};
$.extend(data, _initData );
ko.mapping.fromJS(data, {}, _viewModel);
});
//when updating whole object from server
$("#updateFromServer).live("click", function(){
$.post("/loadMeUp", {}, function (data) {
$.extend(_initData , data);
ko.mapping.fromJS(data, {}, _viewModel);
});
});
//to just load a single item within the observable (for instance, nested objects)
$("#updateSpecificItemFromServer).live("click", function(){
$.post("/loadMeUpSpecificItem", {}, function (data) {
$.extend(_initData.SpecificItem, data);
ko.mapping.fromJS(data, {}, _viewModel.SpecificItem);
});
});
//updating subItems from both lists
$(".removeSpecificItem").live("click", function(){
//object id = "element_" + id
var id = this.id.split("_")[1];
$.post("/deleteSpecificItem", { itemID: id }, function(data){
//Table of items with the row elements id = "tr_" + id
$("#tr_" + id).remove();
$.each(_viewModel.SpecificItem.Members, function(index, value){
if(value.ID == id)
_viewModel.SpecificItem.Members.splice(index, 1);
});
$.each(_initData.SpecificItem.Members, function(index, value){
if(value.ID == id)
_initData.SpecificItem.Members.splice(index, 1);
});
});
});
});
我有一个足够复杂的对象,我不想为每个单独的属性添加处理程序。
实时对我的对象进行了一些更改,这些更改同时编辑了 observable 和“_initData”。
当我从服务器取回数据时,我会更新我的“_initData”对象以尝试使其与服务器保持同步。