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...)

Johy
  • 317
  • 1
  • 5
  • 16

4 Answers4

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.

jnuno
  • 711
  • 5
  • 8
  • 1
    You're the one who wrote this library right? Then, is there a difference with simply doing: `tree.parse(root.model);`? – Johy Dec 15 '14 at 11:14
  • Fantastic. Thank you so much for both the library and this answer. ;-) – Johy Dec 15 '14 at 11:18
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.

Johy
  • 317
  • 1
  • 5
  • 16
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.

A. Rama
  • 903
  • 8
  • 18
  • 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: http://jsfiddle.net/pvzb9vd2/5/ – Johy Dec 15 '14 at 10:34
  • 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. – A. Rama Dec 15 '14 at 10:49
  • 1
    I think I found this solution: var dup2 = tree.parse(root.model) *Edit: ok , you found it as well :) – A. Rama Dec 15 '14 at 11:10
0

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

newTree = deepCopy(tree)

Arbaaz
  • 11
  • 3