如何使用递归函数 select 使用角度 ui 树的树数组中的父级?
how to use recursive function to select the parent in a tree array using angulat ui tree?
所以,我正在尝试创建一个分层树。当一个节点 selected 有子节点时,该节点的所有子节点都会被 selected,但是当我 select 所有子节点时,我也想 select 父节点.
这里有一个 link 给 plunker:
[https://plnkr.co/plunk/iMBFfy6cf7urOHhZ][1]
我已经创建了一个目录来标记树
TreeController.js
(function (ng) {
var app = ng.module('tree', ['tree.service', 'tree.directives']);
app.controller("TreeController", ["TreeService", "$scope", function (TreeService, $scope) {
var tc = this;
buildTree();
function buildTree() {
TreeService.getTree().then(function (result) {
tc.tree = result.data;
}, function (result) {
alert("Tree no available, Error: " + result);
});
}
$scope.selectedItems = [];
$scope.getSelected = function(){
$scope.selectedItems = [];
function checkChildren(c) {
angular.forEach(c.children, function (c) {
if (c.checked){
$scope.selectedItems.push({"selected":c.name});
}
checkChildren(c);
});
}
angular.forEach(tc.tree, function(value, key) {
if (value.checked){
$scope.selectedItems.push({"selected":value.name});
}
checkChildren(value);
});
};
}]);
})(angular);
index.html
<div ng-controller="TreeController as tc">
<ul class="tree">
<node-tree children="tc.tree"></node-tree>
</ul>
<button ng-click="getSelected()">Get Selected</button>
<br/>
<br/>
Selected:
<ul>
<li ng-repeat="item in selectedItems">
{{item.selected}}
</li>
</ul>
</div>
TreeDirective.js
(function (ng) {
var app = ng.module('tree.directives', []);
app.directive('nodeTree', function () {
return {
template: '<node ng-repeat="node in tree"></node>',
replace: true,
restrict: 'E',
scope: {
tree: '=children'
}
};
});
app.directive('node', function ($compile) {
return {
restrict: 'E',
replace: true,
templateUrl: 'node.html', // HTML for a single node.
link: function (scope, element) {
/*
* Here we are checking that if current node has children then compiling/rendering children.
* */
if (scope.node && scope.node.children && scope.node.children.length > 0) {
scope.node.childrenVisibility = true;
var childNode = $compile('<ul class="tree" ng-if="!node.childrenVisibility"><node-tree children="node.children"></node-tree></ul>')(scope);
element.append(childNode);
} else {
scope.node.childrenVisibility = false;
}
},
controller: ["$scope", function ($scope) {
// This function is for just toggle the visibility of children
$scope.toggleVisibility = function (node) {
if (node.children) {
node.childrenVisibility = !node.childrenVisibility;
}
};
// Here We are marking check/un-check all the nodes.
$scope.checkNode = function (node) {
node.checked = !node.checked;
// if (node.checked){
// alert("clicked");
// }
function checkChildren(c) {
angular.forEach(c.children, function (c) {
c.checked = node.checked;
checkChildren(c);
});
}
checkChildren(node);
};
}]
};
});
})(angular);
node.html
<li>
<span ng-click="toggleVisibility(node)"> {{ ( node.childrenVisibility && node.children.length ) ? '+' : '-' }}</span>
<input ng-click="checkNode(node)" type="checkbox" ng-checked="node.checked">
<span>
{{ $index + 1 }}. {{ node.name }}
</span>
</li>
第一步是确定每个节点的 parent 节点是什么。我们可以通过在加载树后立即递归并在每个节点上设置 parent
属性 来做到这一点。
TreeController.js
...
function buildTree() {
TreeService.getTree().then(function (result) {
tc.tree = result.data;
function setParentForChildren(n) {
angular.forEach(n.children, function (c) {
c.parent = n;
setParentForChildren(c);
})
}
angular.forEach(tc.tree, setParentForChildren);
}, function (result) {
alert("Tree no available, Error: " + result);
});
}
...
现在,我们可以在每次选中一个框时使用那个 parent 引用来递归树并说“如果我所有的 children 都被选中,那么我也应该被选中”每个 parent 个节点。
TreeDirective.js
...
$scope.checkNode = function (node) {
node.checked = !node.checked;
function checkParent(n) {
if (!n.parent)
return;
const p = n.parent;
p.checked = p.children.every(function(c) { return c.checked });
checkParent(p);
}
checkParent(node);
function checkChildren(c) {
angular.forEach(c.children, function (c) {
c.checked = node.checked;
checkChildren(c);
});
}
checkChildren(node);
};
...
所以,我正在尝试创建一个分层树。当一个节点 selected 有子节点时,该节点的所有子节点都会被 selected,但是当我 select 所有子节点时,我也想 select 父节点.
这里有一个 link 给 plunker: [https://plnkr.co/plunk/iMBFfy6cf7urOHhZ][1]
我已经创建了一个目录来标记树
TreeController.js
(function (ng) {
var app = ng.module('tree', ['tree.service', 'tree.directives']);
app.controller("TreeController", ["TreeService", "$scope", function (TreeService, $scope) {
var tc = this;
buildTree();
function buildTree() {
TreeService.getTree().then(function (result) {
tc.tree = result.data;
}, function (result) {
alert("Tree no available, Error: " + result);
});
}
$scope.selectedItems = [];
$scope.getSelected = function(){
$scope.selectedItems = [];
function checkChildren(c) {
angular.forEach(c.children, function (c) {
if (c.checked){
$scope.selectedItems.push({"selected":c.name});
}
checkChildren(c);
});
}
angular.forEach(tc.tree, function(value, key) {
if (value.checked){
$scope.selectedItems.push({"selected":value.name});
}
checkChildren(value);
});
};
}]);
})(angular);
index.html
<div ng-controller="TreeController as tc">
<ul class="tree">
<node-tree children="tc.tree"></node-tree>
</ul>
<button ng-click="getSelected()">Get Selected</button>
<br/>
<br/>
Selected:
<ul>
<li ng-repeat="item in selectedItems">
{{item.selected}}
</li>
</ul>
</div>
TreeDirective.js
(function (ng) {
var app = ng.module('tree.directives', []);
app.directive('nodeTree', function () {
return {
template: '<node ng-repeat="node in tree"></node>',
replace: true,
restrict: 'E',
scope: {
tree: '=children'
}
};
});
app.directive('node', function ($compile) {
return {
restrict: 'E',
replace: true,
templateUrl: 'node.html', // HTML for a single node.
link: function (scope, element) {
/*
* Here we are checking that if current node has children then compiling/rendering children.
* */
if (scope.node && scope.node.children && scope.node.children.length > 0) {
scope.node.childrenVisibility = true;
var childNode = $compile('<ul class="tree" ng-if="!node.childrenVisibility"><node-tree children="node.children"></node-tree></ul>')(scope);
element.append(childNode);
} else {
scope.node.childrenVisibility = false;
}
},
controller: ["$scope", function ($scope) {
// This function is for just toggle the visibility of children
$scope.toggleVisibility = function (node) {
if (node.children) {
node.childrenVisibility = !node.childrenVisibility;
}
};
// Here We are marking check/un-check all the nodes.
$scope.checkNode = function (node) {
node.checked = !node.checked;
// if (node.checked){
// alert("clicked");
// }
function checkChildren(c) {
angular.forEach(c.children, function (c) {
c.checked = node.checked;
checkChildren(c);
});
}
checkChildren(node);
};
}]
};
});
})(angular);
node.html
<li>
<span ng-click="toggleVisibility(node)"> {{ ( node.childrenVisibility && node.children.length ) ? '+' : '-' }}</span>
<input ng-click="checkNode(node)" type="checkbox" ng-checked="node.checked">
<span>
{{ $index + 1 }}. {{ node.name }}
</span>
</li>
第一步是确定每个节点的 parent 节点是什么。我们可以通过在加载树后立即递归并在每个节点上设置 parent
属性 来做到这一点。
TreeController.js
...
function buildTree() {
TreeService.getTree().then(function (result) {
tc.tree = result.data;
function setParentForChildren(n) {
angular.forEach(n.children, function (c) {
c.parent = n;
setParentForChildren(c);
})
}
angular.forEach(tc.tree, setParentForChildren);
}, function (result) {
alert("Tree no available, Error: " + result);
});
}
...
现在,我们可以在每次选中一个框时使用那个 parent 引用来递归树并说“如果我所有的 children 都被选中,那么我也应该被选中”每个 parent 个节点。
TreeDirective.js
...
$scope.checkNode = function (node) {
node.checked = !node.checked;
function checkParent(n) {
if (!n.parent)
return;
const p = n.parent;
p.checked = p.children.every(function(c) { return c.checked });
checkParent(p);
}
checkParent(node);
function checkChildren(c) {
angular.forEach(c.children, function (c) {
c.checked = node.checked;
checkChildren(c);
});
}
checkChildren(node);
};
...