如何制作由映射插件创建的基因剔除对象的深层副本 [英] How do I make a deep copy of a knockout object that was created by the mapping plugin

查看:83
本文介绍了如何制作由映射插件创建的基因剔除对象的深层副本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的情况.我正在使用基因剔除映射插件为我创建一个可观察的viewmodel层次结构.我的层次结构中有嵌套的元素.在层次结构中的某个特定点,我想添加一个添加"按钮,以将该元素的新空白副本插入到observablearray中.问题是我不能只说出whatArray.push(new MyObject()).

Here's my scenario. I'm using the knockout mapping plugin to create an observable viewmodel hierarchy for me. My hierarchy has nested elements in it. At a particular point in the hierarchy I want to put an Add button to insert a new blank copy of that element in the observablearray. The problem is I can't just say whateverArray.push(new MyObject()).

由于映射插件实际上为我创建了整个层次结构,因此我无权访问"MyObject".因此,插入新项目似乎唯一可以做的就是查看先前的项目并复制它.我尝试了ko.utils.extend函数,但似乎并没有进行实际的克隆.它给了我一个对象,但是当我更新该对象时,它仍然会影响复制它的原始对象.

Since the mapping plugin actually created the whole hierarchy for me, I don't have access to "MyObject". So it seems the only thing I can do to insert a new item is to look at a previous item and copy it. I tried the ko.utils.extend function, but that doesn't appear to be making an actual clone. It gives me an object back, but when I update that object it still affects the original object that it was copied from.

请参阅jsfiddle 示例

See jsfiddle example

推荐答案

也许可以在映射设置中进行设置,但是我还不太清楚.

There might be a way to set this up in the mapping settings but I can't quite figure that out just yet.

同时,您可以取消映射对象并将其映射回原来的位置,以便进行复制.

In the mean time, you could just unmap the object and map it back so you are essentially making a copy.

var newJob = ko.mapping.fromJS(ko.mapping.toJS(job));

这将是最简单的方法,就像其他任何库一样,再次反序列化"和序列化".

This will be the easiest way to do it just like any other library, "deserialize" and "serialize" back again.

我一直在寻找一种使用映射选项来完成此操作的好方法,并且找到了一种方法.

I was looking hard for a nice way to do this using the mapping options and found a way.

默认情况下,映射插件将从源对象中获取可观察到的实例,并在目标对象中使用相同的实例.因此,实际上,两个实例将共享相同的可观察对象(错误?).我们需要做的是为每个属性创建一个新的可观察对象,然后将值复制过来.

By default, the mapping plugin will take the observable instances from the source object and use the same instance in the target object. So in effect, both instances will share the same observables (bug?). What we needed to do was create a new observable for each property and copy the values over.

幸运的是,有一个方便的实用程序函数可以映射出对象的每个属性.然后,我们可以创建新的可观察实例,并使用值的副本进行初始化.

Fortunately, there is a handy utility function to map out each of the properties of an object. We can then create our new observable instances initialized with copies of the values.

// Deep copy
var options = {
    create: function (options) {
        // map each of the properties
        return ko.mapping.visitModel(options.data, function (value) {
            // create new instances of observables initialized to the same value
            if (ko.isObservable(value)) { // may want to handle more cases
                return ko.observable(value);
            }
            return value;
        });
    }
};
var newJob = ko.mapping.fromJS(job, options);

请注意,这将是一个浅表副本,如果要深表副本,则可能必须递归映射对象.但是,这将解决您的示例中的问题.

Note that this will be a shallow copy, you'll probably have to recursively map the objects if you want a deep copy. This will fix the problem in your example however.

这篇关于如何制作由映射插件创建的基因剔除对象的深层副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆