2013-12-12 19 views
6

Ich versuche, eine Funktion zu erstellen, die eine baumartige Struktur generiert, so dass jedes Element einen Verweis auf das übergeordnete Element enthält.Javascript rekursive Funktion Referenz dieser

Ich habe eine Funktion, die sich selbst beim Erstellen der Kinder nennt, aber habe eine harte Zeit damit, es scheint, dass, sobald es von sich selbst aufgerufen wird this bezieht sich immer noch auf die oberste Ebene Element als die aktuelle.

Logging, um zu konsolen, was das Element ist, kann ich sehen, dass Eltern immer auf das erste Element in der Kette verweist (oder abwesend ist), wenn tiefer als die erste Ebene. Es erstellt den Baum, aber Verweise auf Eltern sind für Elemente neben dem ersten verloren.

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, {}); 

ein wenig Mühe Mit einer Geige in Gang zu bringen, aber hier einige Beispieldaten:

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"}]}'); 
+0

Nur ein Tippfehler, hatte ich experimentiert und vergessen, es vor dem Posten zurück zu ändern. Es ist hier behoben, das Problem ist immer noch das gleiche. – JPR

+1

Kannst du mit Dummy-Daten dafür etwas schaffen? –

+0

Sicher, könnte ein paar Minuten dauern, um es zusammen zu bekommen. Vielen Dank. – JPR

Antwort

1

Das Problem in Ihrer Nutzung der _.without method ist. Die auszuschließenden Elemente werden als variable Anzahl von Argumenten übergeben, nicht als Array.

Falsche Nutzung:

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

Ergebnisse in ['a', 'b'] (nicht das, was Sie wollen)

Während:

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

ergibt Ihr erwartetes Ergebnis: ['b']

Hier ist ein updated fiddle mit Die Reparatur.

Hinweis: Um die zyklische Referenz zu vermeiden, drucke ich die parent.id anstelle von parent im Ausgang "Result" aus.

1

Es macht den Job für mich. Ich habe den Code etwas vereinfacht und den Enkel hinzugefügt. Werfen Sie einen Blick: 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; 

Das Problem wurde _.without(), die eher eine Liste nimmt dann ein Array als zweiten Parameter.

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

Dies funktioniert: http://jsfiddle.net/eRbhm/13/

+0

Danke und Daumen hoch für das. Ich habe deine erste Antwort versucht und es hat funktioniert, aber mein Code hat es immer noch nicht getan und ich konnte nicht herausfinden, dass deine Version grundlegend anders ist als das, was ich gemacht habe. Reparieren, ohne es sofort zu beheben, ich hatte es total übersehen. – JPR