如何获得递归树视图工作的AngularJs

问题描述 投票:0回答:1

正在使用此AngularJs(1.4)代码段,需要帮助才能使递归树视图按需工作。

它目前有4个等级,需要的是:

  1. 当我打开一个文件夹时,它应该关闭相同级别的所有文件夹(包括其子级和子级子)。

它适用于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>
javascript angularjs treeview angular-ui-bootstrap angular-ui
1个回答
0
投票

环顾四周后,决定使用更好的递归模板替换以前的实现:

更新后的代码: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>
© www.soinside.com 2019 - 2024. All rights reserved.