Cloning a JS TreeModel tree
Asked Answered
I

4

7

I need to clone a tree I made using TreeModel.js. What I exactly need to do is duplicating it, make changes to it and check if the number of nodes decreased. If it did, revert to the original tree. Here's a small example of what I do so far to duplicate it, which is not correct:

var tree = new TreeModel();
var root = tree.parse({
    id: 0,
    name: "Root",
    children: [{id: 1, name: "1", children: []},{id: 2, name: "2", children: []}]
});

console.log(root)
var dup = tree.parse(root)
console.log(dup)

Here's a Fiddle. You'll see the difference between the trees by looking at the console:

Node {config: Object, model: Object, children: Array[2], isRoot: function, hasChildren: function…}
Node {config: Object, model: Node, children: Array[2], isRoot: function, hasChildren: function…}

Is there any way to properly clone such a structure? I looked for cloning JS object but still, I can't find a way for cloning this object exactly (such as the prototypes of properties like the model...)

Insufficiency answered 15/12, 2014 at 9:58 Comment(0)
W
3

You can deep clone the model of the first tree and parse it again to get a second tree.

Taking on your example:

function deepCopy(obj) {
    // You can also use the jquery extend method here
    return JSON.parse(JSON.stringify(obj));
}

var dup = tree.parse(deepCopy(root.model));

Important: If you do not deep clone the model, and just parse it again, you'll end up with the same underlying model shared by both trees which will certainly cause inconsistencies.

Williawilliam answered 15/12, 2014 at 11:9 Comment(2)
You're the one who wrote this library right? Then, is there a difference with simply doing: tree.parse(root.model);?Insufficiency
Fantastic. Thank you so much for both the library and this answer. ;-)Insufficiency
I
1

I finally came to a solution that may help anyone with the same problem:

var tree = new TreeModel();
var root = tree.parse({
    id: 0,
    name: "Root",
    children: [{id: 1, name: "1", children: []},{id: 2, name: "2", children: []}]
});

console.log(root)
var dup = tree.parse(root.model)
console.log(dup)

The parse function takes a model as parameter and the model of root seems to work fine.

EDIT: this solution may bring inconsistencies since the 2 trees are based on the same model. JNS's solution is more appropriate.

Insufficiency answered 15/12, 2014 at 10:52 Comment(0)
J
0

Why not trying a jQuery deep copy?

var dup = jQuery.extend(true, {}, tree)

I tried your fiddle but it doesn't seem to work.

Jacquettajacquette answered 15/12, 2014 at 10:30 Comment(3)
Did you check the console? That's where I can check the structure. Yes, I tried a deep copy but still, I can't get an exact replica. Have a look at the console in this updated Fiddle: jsfiddle.net/pvzb9vd2/5Insufficiency
Yeah, I realized only too late that you were not writing in the "log" div but on the console. And I agree, that's not the same object really.Jacquettajacquette
I think I found this solution: var dup2 = tree.parse(root.model) *Edit: ok , you found it as well :)Jacquettajacquette
A
0

https://github.com/mrluc/owl-deepcopy this worked for me.

newTree = deepCopy(tree)

Amaleta answered 24/6, 2016 at 7:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.