2012-05-10 60 views
11

在Knockout中克隆Observable對象以創建一種事務機制的最佳方法是什麼?

例如編輯這種模式:
克隆observables的最佳方法是什麼?

var Action = function (name, ownerType, condition, expression, args) { 
    var self = this; 
    this.name = ko.observable(name); 
    this.ownerType = ko.observable(ownerType); 
    this.condition = ko.observable(condition); 
    this.expression = ko.observable(expression); 
    this.args = ko.observable(args); 
}; 

我要保存對象的狀態之前,用戶將編輯。如果用戶將取消編輯 - 回滾對象狀態。

簡單的方法是創建一個像另一個項目:

self.tempAction = new Action(action.name(), action.ownerType(), action.condition(), action.expression(), action.args()); 

但我不知道它是優雅的解決方案..

因此,任何想法?

回答

15

我通常做類似如下:

首先我有一個功能,模仿jQuery的$.extend功能。它使用source對象的所有observable(或不可觀察)屬性值填充對象target

// extends observable objects intelligently 
ko.utils.extendObservable = function (target, source) { 
    var prop, srcVal, isObservable = false; 

    for (prop in source) { 

     if (!source.hasOwnProperty(prop)) { 
      continue; 
     } 

     if (ko.isWriteableObservable(source[prop])) { 
      isObservable = true; 
      srcVal = source[prop](); 
     } else if (typeof (source[prop]) !== 'function') { 
      srcVal = source[prop]; 
     } 

     if (ko.isWriteableObservable(target[prop])) { 
      target[prop](srcVal); 
     } else if (target[prop] === null || target[prop] === undefined) { 

      target[prop] = isObservable ? ko.observable(srcVal) : srcVal; 

     } else if (typeof (target[prop]) !== 'function') { 
      target[prop] = srcVal; 
     } 

     isObservable = false; 
    } 
    return target; 
}; 

然後,我有一個copy功能,基本上轉換的對象被複制到JSON,然後採取JSON副本,並建立一個新的JavaScript對象。這可確保所有內存指針都不會被複制,並且您擁有與原始內容匹配的全新對象。這裏的一個關鍵是,你必須在一個新的對象的空實例通過(否則我們根本不知道填充什麼屬性)

// then finally the clone function 
ko.utils.clone = function(obj, emptyObj){ 
    var json = ko.toJSON(obj); 
    var js = JSON.parse(json); 

    return ko.utils.extendObservable(emptyObj, js); 
}; 

然後,您可以使用它,像這樣:

var tempAction = ko.utils.clone(action, new Action()); 
+0

難道你不只是使用ko.mapping插件從原始源對象映射到新的目標對象? – jaffa

+0

@jaffa - 是的,映射插件將是一個合適的選項。然而,對於微不足道的需求來說,這可能是過度的。另外,我發現'extendObservable'函數在映射插件不需要應用程序範圍的情況下非常有用。 – ericb

+0

這是如何與ko.computed值一起使用的?我會認爲使用toJSON和JSON.parse複製一個對象將失去其所有計算值。 –

相關問題