【问题标题】:How to get recursive Tree view working AngularJs如何让递归树视图工作AngularJs
【发布时间】:2020-01-17 10:41:45
【问题描述】:

处理这个 AngularJs(1.4) 代码 sn-p 并需要帮助才能使递归树视图按需要工作。

目前有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】:

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

    更新的插件:enter link description here

    更新了 sn-p:

        $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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-24
      • 1970-01-01
      • 2017-01-20
      • 1970-01-01
      • 1970-01-01
      • 2011-07-21
      相关资源
      最近更新 更多