问题
I'm trying to create a breadcrumb without using the url (the route provider) and without using jQuery. I have a tree like that
Humans
Trees
Animals
Cats
Lions
Dogs
Terrier
Bulldog
Cocker
Cars
and I'd like when I click on Cocker to display
Animals / Dogs / Cocker
So, I created a recursive function in order to find parent/parents for each element that I click on but it doesn't work correctly. It finds that an element has a parent, it also finds the first parent of an element but it doesn't show the second parent. For instance instead of
Animals / Dogs / Cocker
it shows
Dogs / Cocker
That's my function
var count = 0;
function iterate(obj) {
for(var key in obj) {
var elem = obj[key];
if(key === "children") {
count++;
}
if(typeof elem === "object") {
if(elem.children === undefined){
elem.children = 1;
}
if(elem.children.length !==1){
iterate(elem);
$scope.showTrail = elem.children;
$scope.elem = elem;
}
}
}
if($scope.elem === undefined){
$scope.elem = {};
$scope.elem.children = {};
$scope.elem.roleName = {};
}
for (var i = 0; i<$scope.elem.children.length; i++) {
if($scope.elem.children[i].roleName === selNode.roleName) {
console.log($scope.elem.roleName + " is a parent of " + selNode.roleName);
}
}
}
iterate($scope.treeData);
and that's the JSON
[
{ "roleName" : "Humans", "roleId" : "role2", "children" : [
{ "roleName" : "", "roleId" : "role11", "children" : [] }
]},
{ "roleName" : "Trees", "roleId" : "role2", "children" : [
{ "roleName" : "", "roleId" : "role11", "children" : [] }
]},
{ "roleName" : "Animals", "roleId" : "role2", "children" : [
{ "roleName" : "Cats", "roleId" : "role11", "children" : [
{ "roleName" : "", "roleId" : "role11", "children" : [] }
]},
{ "roleName" : "Lions", "roleId" : "role11", "children" : [
{ "roleName" : "", "roleId" : "role11", "children" : [] }
]},
{ "roleName" : "Dogs", "roleId" : "role11", "children" : [
{ "roleName" : "Terrier", "roleId" : "role11", "children" : [
{ "roleName" : "", "roleId" : "role11", "children" : [] }
]},
{ "roleName" : "Bulldog", "roleId" : "role11", "children" : [
{ "roleName" : "", "roleId" : "role11", "children" : [] }
]},
{ "roleName" : "Cocker", "roleId" : "role11", "children" : [
{ "roleName" : "", "roleId" : "role11", "children" : [] }
]},
]}
]},
{ "roleName" : "Cars", "roleId" : "role2", "children" : [
{ "roleName" : "", "roleId" : "role11", "children" : [] }
]}
]
Any help please, any idea. Thank you very much.
回答1:
You are iterating over the tree, but it won't help if you don't keep some information. The simplest solution to your problem is to build an index of all nodes that points to their parents.
This code will work if roleName
has unique values across the whole tree:
var tree = [
{ "roleName" : "Humans", "roleId" : "role2", "children" : []},
{ "roleName" : "Trees", "roleId" : "role2", "children" : []},
{ "roleName" : "Animals", "roleId" : "role2", "children" : [
{ "roleName" : "Cats", "roleId" : "role11", "children" : []},
{ "roleName" : "Lions", "roleId" : "role11", "children" : []},
{ "roleName" : "Dogs", "roleId" : "role11", "children" : [
{ "roleName" : "Terrier", "roleId" : "role11", "children" : []},
{ "roleName" : "Bulldog", "roleId" : "role11", "children" : []},
{ "roleName" : "Cocker", "roleId" : "role11", "children" : []},
]}
]},
{ "roleName" : "Cars", "roleId" : "role2", "children" : []}
];
var index = {};
function buildIndex(root, children) {
for(var i in children) {
index[children[i].roleName] = root;
buildIndex(children[i].roleName, children[i].children);
}
}
buildIndex("Root", tree);
function getPath(leaf) {
return index[leaf] ? getPath(index[leaf]).concat([leaf]) : [leaf];
}
getPath("Bulldog");// returns ["Root", "Animals", "Dogs", "Bulldog"]
JSFiddle: http://jsfiddle.net/E49Ey/
However it has nothing to do with Angular, except the data resides in the scope. If you have a DOM tree built from this data, then you could get the breadcrumb right from the DOM by going up the tree.
回答2:
Hey I put together a quick plunkr doing what your looking for... except it doesn't reverse-traverse up the data tree.
http://embed.plnkr.co/wAJYiAjy58vUEsg4Kr2C
If your looking to actually looking to run up the data tree let me know and I'll modify the plunkr
回答3:
You can of course solve it with a recursive function similar to what you showed in the question. What about a solution like this:
function getPath(obj, selNode, pathSoFar) {
if (obj.roleName == selNode.roleName) {
return pathSoFar + '\\' + obj.roleName;
}
else if (obj.children) {
for (var i=0 ; i<obj.children.length ; i++) {
var temp = getPath(obj.children[i], selNode,
pathSoFar + '\\' + obj.roleName);
if (temp != null) {
return temp;
}
}
}
return null;
}
getPath(rootObj, selNode, '');
I hope it helps and explains the solution idea.
来源:https://stackoverflow.com/questions/20052900/find-all-the-parents-of-each-element