2016-01-04 6 views
15

मैं https://github.com/tchatel/angular-treeRepeat का उपयोग कर रहा हूं और विस्तारित नोड्स को फ़िल्टर करने का प्रयास कर रहा हूं।AngularJS फ़िल्टर फ़िल्टर किए गए नोड्स का विस्तार नहीं कर रहा है

treeRepeat.html: तो मैं AngularJS फिल्टर शामिल करने के लिए इस कोड को संशोधित कर लिया है

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

यह अगर पेड़ नोड्स के सभी का विस्तार कर रहे हैं के रूप में उम्मीद काम करता है: लाइन 20 controllers.js पर:

$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 } ] } ] } ]"); 

लेकिन अगर नोड्स ध्वस्त हो जाते हैं तो मिलान किए गए नोड्स विस्तारित/देखने योग्य होते हैं। पेड़ गिर गया है। ढह नोड्स के लिए कॉन्फ़िग: 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 } ] } ] } ]"); 

Plunkr: https://plnkr.co/edit/CtXlRfdreolTTc018c0A?p=preview

मैं मैन्युअल रूप से उपयोगकर्ता प्रकार के रूप में नोड्स का विस्तार करने की जरूरत है या वहाँ एक कोणीय config मैं विस्तार करने के लिए उपयोग कर सकते हैं करते हैं इन नोड्स?

मुझे लगता है कि हर उपयोगकर्ता प्रकार आग एक कस्टम समारोह जोड़ने की कोशिश की है:

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()=== के बजाय contains का उपयोग करने की कोशिश की है, बिना सफलता के।

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> 
+0

नहीं सभी परिदृश्य का विस्तार नोड्स में कारगर सिद्ध होगा। सभी का विस्तार करें और 'ए' खोजें। काम करना चाहिए जैसे कि आप 'फाइल ए' खोजते हैं। सही? – Valijon

+0

@ वालिजन हाँ, काम करने लगता है, केवल समस्या यह है कि जब उपयोगकर्ता टेक्स्टबॉक्स से सभी पाठ हटा देता है तो पेड़ का विस्तार होता है, मुझे इस परिदृश्य की जांच करने में सक्षम होना चाहिए और बस पेड़ को फिर से लोड करना चाहिए: https://plnkr.co/edit/CtXlRfdreolTTc018c0A ? पी = पूर्वावलोकन –

+0

@ नीला आकाश क्या आप केवल उन नोड्स पर फ़िल्टर करना चाहते हैं जिन्हें विस्तारित नहीं किया गया है? –

उत्तर

4

आप एक predicate समारोह के साथ एक फिल्टर का उपयोग करके इस लक्ष्य को हासिल कर सकते हैं।

फ़ंक्शन (मान, अनुक्रमणिका): मनमाने ढंग से फ़िल्टर लिखने के लिए एक अनुमानित फ़ंक्शन का उपयोग किया जा सकता है। फ़ंक्शन को सरणी के प्रत्येक तत्व के लिए बुलाया जाता है। अंतिम परिणाम उन तत्वों की एक सरणी है जो भविष्यवाणी के लिए सच साबित हुईं।

  1. एक विधेय समारोह बनाएं

$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; 
    } 
} 
  1. एक समारोह है कि जाँच करता है बनाएं यदि वर्तमान आइटम से मेल खाता हो (इस समारोह कहा जाता है भविष्यवाणी समारोह से)

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; 
} 

3. वर्तमान कार्य के बच्चों के सामानों के माध्यम से एक फ़ंक्शन बनाएं, यह फ़ंक्शन चरण 2 में फ़ंक्शन को कॉल करता है। आप एक रिकर्सिव फ़ंक्शन के साथ समाप्त होते हैं जो सभी स्तरों की जांच करता है।

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; 
} 

आप मिलान आइटम खोजने के रूप में आप false

करने के लिए collapsed मूल्य सेट करें काम कर उदाहरण here

एचटीएमएल

<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> 
+0

धन्यवाद देखें लेकिन "plnkr.co/edit/CtXlRfdreolTTc018c0A?p=preview - नीला आकाश 7 जनवरी 13:22 पर" एक आसान समाधान नहीं है? –

0

angular-treeRepeat मॉड्यूल पूरी तरह खुदाई और एक पुनरावर्ती टेम्पलेट का उपयोग कर पर विचार करें। बेन फोस्टर बताते हैं कि यह इस blog post में कैसे काम करता है और यह एक बहुत ही सुरुचिपूर्ण (और कम बेहद जटिल) समाधान है, मुझे लगता है। फिल्टर के साथ

कार्य उदाहरण:JSFiddle

HTML:

<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' 
    }]; 
    }); 
संबंधित मुद्दे