Javascript recursive function references this

I am trying to create a function that will generate such a tree structure that each element contains a link to its parent element.

I have a function that calls itself when creating child elements, but it's hard for me to work with it, it seems that when it is called from the inside, this still refers to the top-level element, and not to the current one.

Entering the console that element, I see that the parent always refers to the first element in the chain (or is absent) when deeper than the first level. It creates a tree, but parent references are lost for elements other than the first.

 var Item = function (item, parent) { console.log('item is :' + item.name); this.parent = parent; console.log('parent is: ' + parent); var fields = _.union(_.keys(item), _.keys(this.parent)); _.each(_.without(fields, ['parent','children']), function (prop) { this[prop] = angular.isDefined(item[prop]) ? item[prop] : this.parent[prop]; }, this); this.children = []; if (item.children) { this.children = _.map(item.children, function (child) { console.log('this is : ' + this); return new Item(child, this) }, this); } }; var tree = new Item(root, {}); 

You have a bit of trouble getting the fiddle, but here are some sample data:

 var root = JSON.parse('{"id":"1","name":"root item","root":"1","lft":"1","rgt":"22","level":"1","type": "category","parent_id":"1","deadline":null, "children":[ {"id":"2","name":"item 1","root":"1","lft":"14","rgt":"15","level":"2","type":"category","parent_id":"1"}, {"id":"6","name":"item 2","root":"1","lft":"16","rgt":"19","level":"2","type":"category","parent_id":"1"}, {"id":"10","name":"item 3","root":"1","lft":"20","rgt":"21","level":"2","type":"item","parent_id":"1"}]}'); 
+6
source share
2 answers

The problem is using the _.without method. Elements for exclusion are passed as a variable number of arguments, not as an array.

Misuse:

 _.without(['a','b'],['a']) 

leads to ['a', 'b'] (not what you want)

While:

 _.without(['a','b'],'a') 

gives the expected result: ['b']

Here's an updated script with a fix.

Note. To avoid a looping job, I print out parent.id instead of parent in the "Result" output.

+1
source

He does this job for me. I simplified the code a bit and added a grandson element. Take a look: http://jsfiddle.net/7QYQL/1/

 var grandchild = {}; grandchild.name = 'grandchild'; var child = {}; child.name = 'child'; child.children = []; child.children[0] = grandchild; var root = {}; root.name = 'root'; root.children = []; root.children[0] = child; 

Strike>

The problem was _.without (), which takes a list instead of a second array, not an array.

 _.without(fields, 'parent','children') 

This works: http://jsfiddle.net/eRbhm/13/

+1
source

All Articles