2012-05-10 38 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复制一个对象将失去其所有计算值。 –

相关问题