Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/410.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AngularJS过滤器未展开过滤节点_Javascript_Jquery_Angularjs - Fatal编程技术网

Javascript AngularJS过滤器未展开过滤节点

Javascript AngularJS过滤器未展开过滤节点,javascript,jquery,angularjs,Javascript,Jquery,Angularjs,我正在使用并尝试筛选尚未展开的节点。因此,我修改了这段代码以包含AngularJS过滤器: treeRepeat.html: <p id="expand-collapse-all"> <a href="" ng-click="expandAll()">Expand all</a> <a href="" ng-click="collapseAll()">Collapse all</a> </p> Filte

我正在使用并尝试筛选尚未展开的节点。因此,我修改了这段代码以包含AngularJS过滤器:

treeRepeat.html:

<p id="expand-collapse-all">
    <a href="" ng-click="expandAll()">Expand all</a>
    <a href="" ng-click="collapseAll()">Collapse all</a>
</p>


Filter : <input ng-model="myFilter" type="text">

<ul frang-tree>
  <li frang-tree-repeat="node in treeData | filter:myFilter">
      <div><span class="icon"
                 ng-class="{collapsed: node.collapsed, expanded: !node.collapsed}"
                 ng-show="node.children && node.children.length > 0"
                 ng-click="node.collapsed = !node.collapsed"></span>
           <span class="label"
                 ng-class="{folder: node.children && node.children.length > 0}"
                 ng-bind="node.label"
                 ng-click="action(node)"></span>
      </div>
      <ul ng-if="!node.collapsed && node.children && node.children.length > 0"
          frang-tree-insert-children="node.children  | filter:myFilter"></ul>
  </li>
</ul>
但如果节点已折叠,则匹配的节点将展开/可见。这棵树仍然倒下。折叠节点的配置: controllers.js上的第21行:

$scope.treeData = JSON.parse("[ { \"label\": \"root\", \"children\": [ { \"label\": \"folder A\", \"collapsed\": true, \"children\": [ { \"label\": \"folder B\", \"collapsed\": true, \"children\": [ { \"label\": \"file B1\", \"collapsed\": true }, { \"label\": \"file B2\", \"collapsed\": true } ] }, { \"label\": \"file A1\", \"collapsed\": true }, { \"label\": \"file A2\", \"collapsed\": true }, { \"label\": \"file A3\", \"collapsed\": true }, { \"label\": \"file A4\", \"collapsed\": true } ] }, { \"label\": \"folder C\", \"collapsed\": true, \"children\": [ { \"label\": \"folder D\", \"collapsed\": true, \"children\": [ { \"label\": \"folder E\", \"collapsed\": true, \"children\": [ { \"label\": \"file E1\", \"collapsed\": true }, { \"label\": \"file E2\", \"collapsed\": true }, { \"label\": \"file E3\", \"collapsed\": true } ] } ] }, { \"label\": \"folder F\", \"collapsed\": true, \"children\": [ { \"label\": \"file F1\", \"collapsed\": true }, { \"label\": \"file F2\", \"collapsed\": true } ] }, { \"label\": \"file C1\", \"collapsed\": true } ] }, { \"label\": \"folder G\", \"collapsed\": true, \"children\": [ { \"label\": \"file G1\", \"collapsed\": true }, { \"label\": \"file G2\", \"collapsed\": true }, { \"label\": \"file G3\", \"collapsed\": true }, { \"label\": \"file G4\", \"collapsed\": true } ] }, { \"label\": \"folder H\", \"collapsed\": true, \"children\": [ { \"label\": \"file H1\", \"collapsed\": true }, { \"label\": \"file H2\", \"collapsed\": true }, { \"label\": \"file H3\", \"collapsed\": true } ] } ] } ]");
$scope.treeData = JSON.parse("[ { \"label\": \"root\", \"children\": [ { \"label\": \"folder A\", \"collapsed\": true, \"children\": [ { \"label\": \"folder B\", \"collapsed\": true, \"children\": [ { \"label\": \"file B1\", \"collapsed\": true }, { \"label\": \"file B2\", \"collapsed\": true } ] }, { \"label\": \"file A1\", \"collapsed\": true }, { \"label\": \"file A2\", \"collapsed\": true }, { \"label\": \"file A3\", \"collapsed\": true }, { \"label\": \"file A4\", \"collapsed\": true } ] }, { \"label\": \"folder C\", \"collapsed\": true, \"children\": [ { \"label\": \"folder D\", \"collapsed\": true, \"children\": [ { \"label\": \"folder E\", \"collapsed\": true, \"children\": [ { \"label\": \"file E1\", \"collapsed\": true }, { \"label\": \"file E2\", \"collapsed\": true }, { \"label\": \"file E3\", \"collapsed\": true } ] } ] }, { \"label\": \"folder F\", \"collapsed\": true, \"children\": [ { \"label\": \"file F1\", \"collapsed\": true }, { \"label\": \"file F2\", \"collapsed\": true } ] }, { \"label\": \"file C1\", \"collapsed\": true } ] }, { \"label\": \"folder G\", \"collapsed\": true, \"children\": [ { \"label\": \"file G1\", \"collapsed\": true }, { \"label\": \"file G2\", \"collapsed\": true }, { \"label\": \"file G3\", \"collapsed\": true }, { \"label\": \"file G4\", \"collapsed\": true } ] }, { \"label\": \"folder H\", \"collapsed\": true, \"children\": [ { \"label\": \"file H1\", \"collapsed\": true }, { \"label\": \"file H2\", \"collapsed\": true }, { \"label\": \"file H3\", \"collapsed\": true } ] } ] } ]");
普朗克:

我是否需要根据用户类型手动展开节点,或者是否可以使用角度配置来展开这些节点

我已尝试添加一个自定义函数,该函数在每次用户类型时触发:

  function matchChildNode(objData , parentNode) {

        angular.forEach(objData, function(childNode, key) {

                var searchText = "";
                //AngularJS does not initialise the searchText var until used. As the function is re-initialised for every node
                //need to check if is undefined
                if ($scope.searchText == undefined) {
                    searchText = ""
                } else {
                    searchText = $scope.searchText
                }

                if (searchText.toLowerCase() === childNode.label.toLowerCase()) {
                    parentNode.collapsed = false
                }       

                matchChildNode(childNode.children , childNode);

  });
  } 
}
但这是非常低效的,因为它遍历每个关键字用户类型的整个树结构。这也适用于完全匹配的文本:
searchText.toLowerCase()===childNode.label.toLowerCase()
。已尝试使用
包含
而不是
=
,但未成功

plnkr src:

app.css (removed due to stackoverflow 30000 character limitation when asking questions) 

directives.js (removed due to stackoverflow 30000 character limitation when asking questions) 

filter.js : 

'use strict';

angular.module('app.filters', []);

index.html : 


<!doctype html>
<html lang="en" ng-app="app">
<head>
  <meta charset="utf-8">
  <title>treeRepeat demo</title>
  <link rel="stylesheet" href="app.css"/>
</head>

<body>

  <h1>treeRepeat</h1>
  <div id="menu" ng-controller="MenuCtrl">
      <ul>
          <li ng-repeat="item in menu" ng-class="{selected: item == getCurrentMenuItem()}"><a href="#/{{item.index}}">{{item.shortLabel}}</a></li>
      </ul>
      <h2>{{getCurrentMenuItem().fullLabel}}</h2>
  </div>

  <ng-view></ng-view>

  <script src="angular.js"></script>
  <script src="angular-route.js"></script>
  <script src="app.js"></script>
  <script src="services.js"></script>
  <script src="controllers.js"></script>
  <script src="filters.js"></script>
  <script src="directives.js"></script>
</body>
</html>

services.js : 

'use strict';

angular.module('app.services', [])
    .constant('menu', []);

treerepeat.html : 

<p id="expand-collapse-all">
    <a href="" ng-click="expandAll()">Expand all</a>
    <a href="" ng-click="collapseAll()">Collapse all</a>
</p>


Filter : <input ng-model="myFilter" type="text">

<ul frang-tree>
  <li frang-tree-repeat="node in treeData | filter:myFilter">
      <div><span class="icon"
                 ng-class="{collapsed: node.collapsed, expanded: !node.collapsed}"
                 ng-show="node.children && node.children.length > 0"
                 ng-click="node.collapsed = !node.collapsed"></span>
           <span class="label"
                 ng-class="{folder: node.children && node.children.length > 0}"
                 ng-bind="node.label"
                 ng-click="action(node)"></span>
      </div>
      <ul ng-if="!node.collapsed && node.children && node.children.length > 0"
          frang-tree-insert-children="node.children  | filter:myFilter"></ul>
  </li>
</ul>
app.css(由于提问时的字符限制而删除)
directives.js(由于提问时的字符限制而删除)
filter.js:
"严格使用",;
角度模块('app.filters',[]);
index.html:
树重复演示
树泥炭
{{getCurrentMenuItem().fullLabel}} services.js: "严格使用",; angular.module('app.services',[]) .constant('菜单',[]); treerepeat.html:

过滤器:

    考虑完全抛弃
    角度树重复
    模块,并使用递归模板。Ben Foster解释了它是如何工作的,我认为这是一个更优雅(也不那么复杂)的解决方案

    使用过滤器的工作示例:

    HTML:


    您可以通过使用带有函数的过滤器来实现这一点

    函数(值、索引):谓词函数可用于编写任意筛选器。为数组的每个元素调用该函数。最后的结果是谓词为其返回true的那些元素的数组

  • 创建一个谓词函数

  • 创建一个检查当前项是否匹配的函数(此函数从谓词函数调用)


  • 并非所有场景都适用于扩展节点。展开全部并搜索
    A
    。应该像搜索
    文件A
    一样工作。是吗?@Valijon是的,看起来很有效,唯一的问题是当用户从文本框中删除所有文本时,树仍保持展开状态,我应该能够检查此方案并重新加载树:@blue sky是否只对未展开的节点进行筛选?@TjaartvanderWalt我要对所有节点进行筛选,只对包含匹配文本的节点进行展开。@blue sky请查看我的回答谢谢,但我没有“plnkr.co/edit/ctxlrfdrolttc018c0a?p=预览–蓝天1月7日13:22”不是更简单的解决方案吗?
    <div ng-app="app" ng-controller='AppCtrl'>
      Filter: <input ng-model="myFilter" type="text">
      <script type="text/ng-template" id="categoryTree">
        {{ category.title }}
        <ul ng-show="category.categories">
          <li
            ng-repeat="category in category.categories | filter:myFilter"
            ng-include="'categoryTree'">
          </li>
        </ul>
      </script>
      <ul>
        <li
          ng-repeat="category in categories | filter:myFilter"
          ng-include="'categoryTree'">
        </li>
      </ul>
    </div>
    
    var app = angular.module('app', [])
      .controller('AppCtrl', function($scope) {
        $scope.categories = [{
          title: 'Computers',
          categories: [{
              title: 'Laptops',
              categories: [{
                title: 'Ultrabooks'
              },{
                title: 'Macbooks'
              }]
            },{
              title: 'Desktops'
            },{
              title: 'Tablets',
              categories: [{
                title: 'Apple'
              },{
                title: 'Android'
              }]
            }
          ]
        },{
          title: 'Printers'
        }];
      });
    
    $scope.getFilter = function(value, index){
      if(!$scope.myFilter || $scope.myFilter === '' && (value.label === 'root')){
          $scope.collapseAll();
          return true;
      }
      if (findMatch(value, $scope.myFilter)){
          value.collapsed = false;
          return true;
        }else{
          value.collapsed = true;
          return false;
        }
    }
    
    function findMatch(value, filter) {
        var found = false;
        if(value.label.toLowerCase().indexOf(filter) > -1){
            value.collapsed = false;
            found = true;
        }
        if(!value.children || value.children.length===0){
            if(value.collapsed!== undefined){
                value.collapsed = true;
                return found;
              } 
            }
            for (var i = 0; i < value.children.length; i++) {
                if (value.children[i].label.toLowerCase().indexOf(filter) > -1) {
                    //match found
                    value.collapsed = false;
                    value.children[i].collapsed = false;
                    found = true;
                } else {
                    //check child items
                    if(value.children[i].children && value.children[i].children.length>0)
                    {
                      if (findMatchingChildren(value.children[i].children, filter)) {
                        value.children[i].collapsed = false;
                        found = true;
                      }else{
                        value.children[i].collapsed = true;
                      } 
                    }
                }
            }
    
            return found;
    }
    
    function findMatchingChildren(children, filter) {
        var found = false;
        for (var i = 0; i < children.length; i++) {
            if (findMatch(children[i], filter)) {
                children[i].collapsed = false;
                found = true;
            }else{
                children[i].collapsed = true;
            }
        }
        return found;
     } 
    
    <p id="expand-collapse-all">
        <a href="" ng-click="expandAll()">Expand all</a>
        <a href="" ng-click="collapseAll()">Collapse all</a>
    </p>
    Filter : <input ng-model="myFilter" type="text">
    <ul frang-tree>
        <li frang-tree-repeat="node in treeData | filter:getFilter">
            <div>
                <span class="icon"
                    ng-class="{collapsed: node.collapsed, expanded: !node.collapsed}"
                    ng-show="node.children && node.children.length > 0"
                    ng-click="node.collapsed = !node.collapsed"></span>
                <span class="label"
                    ng-class="{folder: node.children && node.children.length > 0}"
                    ng-bind="node.label"
                    ng-click="action(node)"></span>
            </div>
            <ul ng-if="!node.collapsed && node.children && node.children.length>0" frang-tree-insert-children="node.children  | filter:myFilter"></ul>
     </li>
    </ul>