我跑過這篇文章,同時尋找解決類似的問題,並認爲我會張貼我的方法和解決方案的下一個人。
我就跟着你的思路 - 克隆對象,並與「撤銷」舊數據重新填充:
1)數據對象複製到一個新的頁面變量(「_initData」) 2)創建可觀測從原始服務器對象 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」對象以嘗試使其與服務器保持同步。
謝謝,瑞安!我今天在你的網站上看過幾篇文章,但不知何故,我錯過了那篇文章。好東西! – gabrielsond 2011-05-03 20:18:42
謝謝!我現在使用這個代碼,它工作得很好。我進行了修改以使臨時值可觀察。我還添加了一個計算來檢查protectedObservable是否髒。 – Gunslinger 2013-08-21 13:15:12