正在使用此AngularJs(1.4)代码段,需要帮助才能使递归树视图按需工作。
它目前有4个等级,需要的是:
它适用于2级文件夹,但不适用于3,4甚至N级更深的层次。
也可以使用Angular Tree view进行重构,也可以通过轻巧的方式获得相同的结果。
完整Plunker code: https://plnkr.co/edit/vacr1E1sy40mCdSrjW7R?p=preview。
一些代码:
onClickFolder: function(paramFolderId) {
var targetFolderParent = document.getElementById('folder' + paramFolderId) || null;
var parentFolderWithChild = document.getElementById('parentFolder' + paramFolderId) || null;
if (parentFolderWithChild !== null) {
// collapse all children except active
var allChildNodes = document.querySelectorAll(".child");
console.log("all child", allChildNodes)
var childElement = document.getElementById(paramFolderId);
_fnc.collapseAllChildNodes(allChildNodes, paramFolderId);
_fnc.toggleTreeView(childElement);
}
if (targetFolderParent !== null) {
var strClass = targetFolderParent.getAttribute('class');
var selector = "#companyStructureBlock ul i";
_fnc.removeAllIsOpened(targetFolderParent, selector);
targetFolderParent.setAttribute('class', strClass + ' isOpened');
}
},
collapseAllChildNodes: function(allChildNodes, paramFolderId) {
for (i = 0; i < allChildNodes.length; i++) {
var node = angular.element(allChildNodes[i]);
console.log("angular node", node, allChildNodes[i])
if (node.context.id !== "folder" + paramFolderId) {
node.removeClass("expand-folder");
node.addClass("collapse-folder");
} else {
node.addClass("expand-folder");
}
}
},
removeAllIsOpened: function(targetFolderParent, selector) {
//remove all other isOpened class before setting the currentTarget
var allNodes = document.querySelectorAll(selector);
for (var i = 0; i < allNodes.length; i++) {
var node = angular.element(allNodes[i]);
if (targetFolderParent.dataset.level == angular.element(allNodes[i]).context.dataset.level) {
node.removeClass('isOpened');
console.log("here remove all", angular.element(angular.element(node).find("ul .child")).children());
}
}
},
toggleTreeView: function(childElement) {
var collapse = angular.element(childElement).hasClass('collapse-folder');
var expand = angular.element(childElement).hasClass('expand-folder');
if (!expand && !collapse) {
angular.element(childElement).addClass("expand-folder");
} else if (expand & !collapse) {
angular.element(childElement).removeClass("expand-folder");
angular.element(childElement).addClass("collapse-folder");
} else if (!expand & collapse) {
angular.element(childElement).removeClass("collapse-folder");
angular.element(childElement).addClass("expand-folder");
} else if (expand && collapse) {
angular.element(childElement).removeClass("collapse-folder");
angular.element(childElement).addClass("expand-folder");
} else {
angular.element(childElement).addClass("expand-folder");
}
},
};
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="lodash.js@*" data-semver="2.4.1" src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js'></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" />
<link href="style.css" rel="stylesheet">
</head>
<body ng-controller='Ctrl'>
<!-- do stuff -->
<h1>{{title}}</h1>
<style>
#companyStructureBlock {
height: 500px;
max-width: 259px;
overflow: auto;
color: #eee;
resize: horizontal;
}
.gridtable tbody tr td {
padding: 0;
}
.gridtable tbody tr td .col-sm-12 {
padding: 0;
}
.expand-folder {
display: block;
}
.collapse-folder {
display: none;
}
</style>
<div id="companyStructureBlock">
<div>
Structures
</div>
<br>
<i id="folder{{structure.folderId}}" ng-class="companyStructure.rootStructure.blnIsOpened? 'isOpened' : '' " class="fas fa-folder folder" src="{{ui.img.companyStructure.folder}}"> <a ng-click="loadOnDemand($event, companyStructure.rootStructure.folderId,1);filterContactsBasedOnFolder(companyStructure.rootStructure.folderId);"
class="mrm" ng-bind="companyStructure.rootStructure.levelName | limitTo:20:' ...'"></a></i>
<ul ng-repeat="structure in structureData | orderBy: ['-unassignedSubstructure','folderId']" id="parentFolder{{structure.folderId}}">
<i id="folder{{structure.folderId}}" class="fas fa-folder folder" src="{{ui.img.companyStructure.folderplus}}" data-level="{{structure.level}}">
<a ng-click="loadOnDemand($event,structure.folderId,structure.level);filterContactsBasedOnFolder(structure.folderId);" class="mrm"
ng-bind="structure.levelName"></a></i>
<ul id="{{structure.folderId}}" class="child">
</ul>
</ul>
<br>
<i id="folder{{structure.folderId}}" class="fas">
<a ng-click="loadOnDemand($event, companyStructure.rootStructure.folderId,1);filterContactsBasedOnFolder(companyStructure.rootStructure.folderId);"
class="mrm">Return to All Contacts</a></i>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.14/angular.min.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.4.js"></script>
<script src="app.js"></script>
<script src="factory.js"></script>
<script src="controller.js"></script>
</body>
</html>
环顾四周后,决定使用更好的递归模板替换以前的实现:
更新后的代码:enter link description here
更新的代码段:
$scope.expand = [];
$scope.triggerExpand = function(folderId, parentId, level) {
var i = $scope.expand.indexOf(folderId);
var ii = $scope.expand.indexOf(parentId);
if (i >= 0) $scope.expand.length = i;
else {
if ($scope.expand.length > level - 2) {
$scope.expand.length = level - 2;
}
$scope.expand.push(folderId);
}
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="lodash.js@*" data-semver="2.4.1" src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js'></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" />
<link href="style.css" rel="stylesheet">
</head>
<body ng-controller='Ctrl'>
<!-- do stuff -->
<h1>{{title}}</h1>
<style>
#companyStructureBlock {
height: 500px;
max-width: 259px;
overflow: auto;
color: #eee;
resize: horizontal;
}
.gridtable tbody tr td {
padding: 0;
}
.gridtable tbody tr td .col-sm-12 {
padding: 0;
}
.expand-folder {
display: block;
}
.collapse-folder {
display: none;
}
li > * {
vertical-align: text-top;
list-style:none;
}
</style>
<div id="companyStructureBlock">
<div>
Structures
</div>
<br>
<br>
<ul>
<li>
<i id="folder{{companyStructure.rootStructure.folderId}}" class="fas fa-folder folder isOpened" src="{{ui.img.companyStructure.folderplus}}" data-level="{{structure.level}}">
<a class="mrm">{{ companyStructure.rootStructure.levelName }}</a></i>
<ul>
<li ng-repeat="structure in structureData | filter: { parentFolderId : '' } | orderBy: ['-unassignedSubstructure','folderId']" ng-click="triggerExpand(structure.folderId, structure.parentFolderId, structure.level); $event.stopPropagation();">
<i id="folder{{structure.folderId}}" class="fas fa-folder folder" src="{{ui.img.companyStructure.folderplus}}" data-level="{{structure.level}}" ng-class="expand.indexOf(structure.folderId) > -1 ? 'isOpened' : '' " >
<a class="mrm">{{ structure.levelName }}</a></i>
<div ng-include="'menu'"></div>
</li>
</ul>
</li>
</ul>
<i id="folder{{structure.folderId}}" class="fas">
<a ng-click="loadOnDemand($event, companyStructure.rootStructure.folderId,1);filterContactsBasedOnFolder(companyStructure.rootStructure.folderId);"
class="mrm">Return to All Contacts</a></i>
</div>
<script type="text/ng-template" id="menu">
<ul ng-show="expand.length > structure.level-2 && expand[structure.level-2] == structure.folderId">
<li ng-repeat="structure in companyStructure.subStructures | filter: { parentFolderId : structure.folderId } | orderBy: ['folderId']" ng-click="triggerExpand(structure.folderId, structure.parentFolderId, structure.level); filterContactsBasedOnFolder(structure.folderId); $event.stopPropagation();" >
<i id="folder{{structure.folderId}}" class="fas fa-folder folder" src="{{ui.img.companyStructure.folderplus}}" data-level="{{structure.level}}" ng-class="expand.indexOf(structure.folderId) > -1 ? 'isOpened' : '' " >
<a class="mrm">{{ structure.levelName }}</a>
<div ng-include="'menu'"></div>
</i>
</li>
</ul>
</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.14/angular.min.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.4.js"></script>
<script src="app.js"></script>
<script src="factory.js"></script>
<script src="controller.js"></script>
</body>
</html>