कोणीय निर्देशों में पुनरावृत्ति


178

वहाँ लोकप्रिय पुनरावर्ती कोणीय निर्देश क्यू एंड ए के कुछ जोड़े हैं, जो सभी निम्नलिखित समाधानों में से एक में आते हैं:

पहले वाले को समस्या है कि आप पहले से संकलित कोड को हटा नहीं सकते हैं जब तक आप मैन्युअल रूप से संकलन प्रक्रिया का प्रबंधन नहीं करते। दूसरे दृष्टिकोण की समस्या है ... एक निर्देश नहीं होने और अपनी शक्तिशाली क्षमताओं को याद नहीं करने पर, लेकिन अधिक तत्काल, यह उसी तरह से पैरामीटर नहीं किया जा सकता है जिस तरह से एक निर्देश हो सकता है; यह बस एक नए नियंत्रक उदाहरण के लिए बाध्य है।

मैं मैन्युअल रूप से angular.bootstrapया @compile()लिंक फ़ंक्शन में काम कर रहा हूं , लेकिन मुझे हटाने और जोड़ने के लिए मैन्युअल रूप से ट्रैक रखने की समस्या के साथ छोड़ देता है।

क्या कोई पैरामीटर पुनरावर्ती पैटर्न है जो रनटाइम स्थिति को प्रतिबिंबित करने के लिए तत्वों को जोड़ने / हटाने का प्रबंधन करता है? यह कहना है, एक पेड़ जोड़ें / हटाएँ नोड बटन और कुछ इनपुट क्षेत्र जिसका मूल्य एक नोड के बच्चे नोड नीचे पारित किया है। शायद जंजीरों के स्कोप के साथ दूसरे दृष्टिकोण का एक संयोजन (लेकिन मुझे नहीं पता कि यह कैसे करना है)?

जवाबों:


316

@ Dnc253 द्वारा वर्णित धागे में वर्णित समाधानों से प्रेरित होकर, मैंने एक सेवा में पुनरावृत्ति कार्यक्षमता को सार किया ।

module.factory('RecursionHelper', ['$compile', function($compile){
    return {
        /**
         * Manually compiles the element, fixing the recursion loop.
         * @param element
         * @param [link] A post-link function, or an object with function(s) registered via pre and post properties.
         * @returns An object containing the linking functions.
         */
        compile: function(element, link){
            // Normalize the link parameter
            if(angular.isFunction(link)){
                link = { post: link };
            }

            // Break the recursion loop by removing the contents
            var contents = element.contents().remove();
            var compiledContents;
            return {
                pre: (link && link.pre) ? link.pre : null,
                /**
                 * Compiles and re-adds the contents
                 */
                post: function(scope, element){
                    // Compile the contents
                    if(!compiledContents){
                        compiledContents = $compile(contents);
                    }
                    // Re-add the compiled contents to the element
                    compiledContents(scope, function(clone){
                        element.append(clone);
                    });

                    // Call the post-linking function, if any
                    if(link && link.post){
                        link.post.apply(null, arguments);
                    }
                }
            };
        }
    };
}]);

जो निम्नानुसार उपयोग किया जाता है:

module.directive("tree", ["RecursionHelper", function(RecursionHelper) {
    return {
        restrict: "E",
        scope: {family: '='},
        template: 
            '<p>{{ family.name }}</p>'+
            '<ul>' + 
                '<li ng-repeat="child in family.children">' + 
                    '<tree family="child"></tree>' +
                '</li>' +
            '</ul>',
        compile: function(element) {
            // Use the compile function from the RecursionHelper,
            // And return the linking function(s) which it returns
            return RecursionHelper.compile(element);
        }
    };
}]);

डेमो के लिए इस प्लंकर को देखें । मुझे यह घोल सबसे अच्छा लगता है क्योंकि:

  1. आपको एक विशेष निर्देश की आवश्यकता नहीं है जो आपके html को कम स्वच्छ बनाता है।
  2. रिकर्सन लॉजिक को रिकर्सियन हेल्पर सेवा में दूर किया जाता है, इसलिए आप अपने निर्देशों को साफ रखें।

अद्यतन: कोणीय 1.5.x के रूप में, अधिक चाल की आवश्यकता नहीं है, लेकिन केवल टेम्पलेट के साथ काम करता है , टेम्पलेट टेम्पलेट के साथ नहीं


3
धन्यवाद, महान समाधान! वास्तव में साफ और मेरे लिए दो निर्देशकों के बीच पुनरावृत्ति करने के लिए बॉक्स से बाहर काम किया जिसमें एक दूसरे का काम शामिल है।
jssebastian

6
मूल समस्या यह है कि जब आप पुनरावर्ती निर्देशों का उपयोग करते हैं तो AngularJS एक अंतहीन लूप में हो जाता है। यह कोड निर्देश के संकलित घटना के दौरान सामग्री को हटाकर इस लूप को तोड़ देता है, और निर्देश की लिंक घटना में सामग्री को संकलित और फिर से जोड़ देता है।
मार्क लैगेंडीजक

15
अपने उदाहरण में आप के compile: function(element) { return RecursionHelper.compile(element); }साथ बदल सकते हैं compile: RecursionHelper.compile
पाओलो मोरेटी

1
यदि आप चाहते हैं कि टेम्पलेट किसी बाहरी फ़ाइल में स्थित हो तो क्या होगा?
CodyBugstein

2
यह इस अर्थ में सुरुचिपूर्ण है कि यदि / जब कोणीय कोर एक समान समर्थन लागू करता है, तो आप कस्टम संकलन आवरण को हटा सकते हैं और शेष सभी कोड समान रहेंगे।
कार्लो बोनामिको

25

तत्वों को मैन्युअल रूप से जोड़ना और उनका संकलन करना निश्चित रूप से एक सही दृष्टिकोण है। यदि आप एनजी-रिपीट का उपयोग करते हैं तो आपको तत्वों को मैन्युअल रूप से हटाने की आवश्यकता नहीं होगी।

डेमो: http://jsfiddle.net/KNM4q/113/

.directive('tree', function ($compile) {
return {
    restrict: 'E',
    terminal: true,
    scope: { val: '=', parentData:'=' },
    link: function (scope, element, attrs) {
        var template = '<span>{{val.text}}</span>';
        template += '<button ng-click="deleteMe()" ng-show="val.text">delete</button>';

        if (angular.isArray(scope.val.items)) {
            template += '<ul class="indent"><li ng-repeat="item in val.items"><tree val="item" parent-data="val.items"></tree></li></ul>';
        }
        scope.deleteMe = function(index) {
            if(scope.parentData) {
                var itemIndex = scope.parentData.indexOf(scope.val);
                scope.parentData.splice(itemIndex,1);
            }
            scope.val = {};
        };
        var newElement = angular.element(template);
        $compile(newElement)(scope);
        element.replaceWith(newElement);
    }
}
});

1
मैंने आपकी स्क्रिप्ट को अपडेट किया है ताकि उसका केवल एक निर्देश हो। jsfiddle.net/KNM4q/103 हम उस डिलीट बटन को कैसे काम कर सकते हैं?
बेनी बोटेमा

बहुत अच्छा! मैं बहुत करीब था, लेकिन @position नहीं था (मुझे लगा कि मैं इसे माता-पिता के साथ पा सकता हूं [val]। यदि आप अंतिम संस्करण ( jsfiddle.net/KNM4q/111 ) के साथ अपने उत्तर को अपडेट करते हैं तो मैं इसे स्वीकार करूंगा।
बेनी बोटेमा

12

मुझे यकीन नहीं है कि अगर यह समाधान आपके द्वारा जुड़े उदाहरणों या उसी मूल अवधारणा में से एक में पाया जाता है, लेकिन मुझे एक पुनरावर्ती निर्देश की आवश्यकता थी, और मुझे एक महान, आसान समाधान मिला

module.directive("recursive", function($compile) {
    return {
        restrict: "EACM",
        priority: 100000,
        compile: function(tElement, tAttr) {
            var contents = tElement.contents().remove();
            var compiledContents;
            return function(scope, iElement, iAttr) {
                if(!compiledContents) {
                    compiledContents = $compile(contents);
                }
                iElement.append(
                    compiledContents(scope, 
                                     function(clone) {
                                         return clone; }));
            };
        }
    };
});

module.directive("tree", function() {
    return {
        scope: {tree: '='},
        template: '<p>{{ tree.text }}</p><ul><li ng-repeat="child in tree.children"><recursive><span tree="child"></span></recursive></li></ul>',
        compile: function() {
            return  function() {
            }
        }
    };
});​

आपको recursiveनिर्देश बनाना चाहिए और फिर इसे उस तत्व के चारों ओर लपेटना चाहिए जो पुनरावर्ती कॉल करता है।


1
@MarkError और @ dnc253 यह मददगार है, हालाँकि मुझे हमेशा निम्न त्रुटि प्राप्त होती है:[$compile:multidir] Multiple directives [tree, tree] asking for new/isolated scope on: <recursive tree="tree">
Jack

1
यदि कोई अन्य व्यक्ति इस त्रुटि का सामना कर रहा है, तो बस आप (या योमेन) ने किसी भी जावास्क्रिप्ट फाइल को एक से अधिक बार शामिल नहीं किया है। किसी तरह मेरी main.js फ़ाइल को दो बार शामिल किया गया था और इसलिए एक ही नाम वाले दो निर्देश बनाए जा रहे थे। जेएस में से एक को हटाने के बाद, कोड ने काम किया।
जैक

2
@Jack यह इंगित करने के लिए धन्यवाद। बस इस मुद्दे को शूट करने में कई घंटे की परेशानी का सामना करना पड़ता है और आपकी टिप्पणी ने मुझे सही दिशा में ले जाने के लिए कहा। ASP.NET उपयोगकर्ताओं को बंडलिंग सेवा का उपयोग करने के लिए, सुनिश्चित करें कि आपके पास निर्देशिका में किसी फ़ाइल का पुराना छोटा संस्करण नहीं है, जबकि आप बंडलिंग में वाइल्डकार्ड का उपयोग करते हैं।
Beyers

मेरे लिए, कॉलबैक के अंदर जोड़ने के लिए तत्व की आवश्यकता है: compiledContents(scope,function(clone) { iElement.append(clone); });.अन्यथा, "आवश्यकता" एड नियंत्रक को सही ढंग से नियंत्रित नहीं किया गया है, और त्रुटि, Error: [$compile:ctreq] Controller 'tree', required by directive 'subTreeDirective', can't be found!कारण।
त्सुनेओ योशिओका

मैं कोणीय js के साथ पेड़ की संरचना उत्पन्न करने की कोशिश कर रहा हूं, लेकिन इसके साथ अटक गया।
लर्निंग-ओवरथिंकर-भ्रमित

10

कोणीय 1.5.x के रूप में, अधिक चाल की आवश्यकता नहीं है, निम्नलिखित संभव किया गया है। चारों ओर गंदे काम की कोई ज्यादा जरूरत नहीं!

यह खोज एक पुनरावर्ती निर्देश के लिए एक बेहतर / क्लीनर समाधान के लिए मेरे शिकार के उत्पाद द्वारा थी। आप इसे यहाँ पा सकते हैं https://jsfiddle.net/cattails27/5j5au76c/ । यह समर्थन करता है जहाँ तक 1.3.x है।

angular.element(document).ready(function() {
  angular.module('mainApp', [])
    .controller('mainCtrl', mainCtrl)
    .directive('recurv', recurveDirective);

  angular.bootstrap(document, ['mainApp']);

  function recurveDirective() {
    return {
      template: '<ul><li ng-repeat="t in tree">{{t.sub}}<recurv tree="t.children"></recurv></li></ul>',
      scope: {
        tree: '='
      },
    }
  }

});

  function mainCtrl() {
    this.tree = [{
      title: '1',
      sub: 'coffee',
      children: [{
        title: '2.1',
        sub: 'mocha'
      }, {
        title: '2.2',
        sub: 'latte',
        children: [{
          title: '2.2.1',
          sub: 'iced latte'
        }]
      }, {
        title: '2.3',
        sub: 'expresso'
      }, ]
    }, {
      title: '2',
      sub: 'milk'
    }, {
      title: '3',
      sub: 'tea',
      children: [{
        title: '3.1',
        sub: 'green tea',
        children: [{
          title: '3.1.1',
          sub: 'green coffee',
          children: [{
            title: '3.1.1.1',
            sub: 'green milk',
            children: [{
              title: '3.1.1.1.1',
              sub: 'black tea'
            }]
          }]
        }]
      }]
    }];
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<div>
  <div ng-controller="mainCtrl as vm">
    <recurv tree="vm.tree"></recurv>
  </div>
</div>


1
इसके लिए धन्यवाद। क्या आप मुझे उस चैंज से जोड़ सकते हैं जिसने यह सुविधा शुरू की है? धन्यवाद!
स्टीवन

कोणीय 1.5.x का उपयोग करना बहुत महत्वपूर्ण है। 1.4.x काम नहीं करेगा और वास्तव में jsfiddle में उपलब्ध कराया गया संस्करण है।
12

jsfiddle jsfiddle.net/cattails27/5j5au76c में इस उत्तर का समान कोड नहीं है ... क्या यह सही है? मुझे क्या याद आ रहा है?
पाओलो बायवती


4

थोड़ी देर के लिए कई वर्कअराउंड का उपयोग करने के बाद, मैं बार-बार इस मुद्दे पर वापस आया हूं।

मैं सेवा समाधान से संतुष्ट नहीं हूं क्योंकि यह निर्देशों के लिए काम करता है जो सेवा को इंजेक्ट कर सकता है लेकिन अनाम टेम्पलेट टुकड़े के लिए काम नहीं करता है।

इसी तरह, जो समाधान निर्देश में DOM हेरफेर करके विशिष्ट टेम्पलेट संरचना पर निर्भर करते हैं वे बहुत विशिष्ट और भंगुर होते हैं।

मुझे लगता है कि मेरा मानना ​​है कि एक सामान्य समाधान है जो पुनरावृत्ति को स्वयं के एक निर्देश के रूप में संलग्न करता है जो किसी भी अन्य निर्देशों के साथ न्यूनतम हस्तक्षेप करता है और इसे गुमनाम रूप से उपयोग किया जा सकता है।

नीचे एक प्रदर्शन है जिसे आप plnkr पर भी देख सकते हैं: http://plnkr.co/edit/MSiwnDFD81HAOXWvQWIM

var hCollapseDirective = function () {
  return {
    link: function (scope, elem, attrs, ctrl) {
      scope.collapsed = false;
      scope.$watch('collapse', function (collapsed) {
        elem.toggleClass('collapse', !!collapsed);
      });
    },
    scope: {},
    templateUrl: 'collapse.html',
    transclude: true
  }
}

var hRecursiveDirective = function ($compile) {
  return {
    link: function (scope, elem, attrs, ctrl) {
      ctrl.transclude(scope, function (content) {
        elem.after(content);
      });
    },
    controller: function ($element, $transclude) {
      var parent = $element.parent().controller('hRecursive');
      this.transclude = angular.isObject(parent)
        ? parent.transclude
        : $transclude;
    },
    priority: 500,  // ngInclude < hRecursive < ngIf < ngRepeat < ngSwitch
    require: 'hRecursive',
    terminal: true,
    transclude: 'element',
    $$tlb: true  // Hack: allow multiple transclusion (ngRepeat and ngIf)
  }
}

angular.module('h', [])
.directive('hCollapse', hCollapseDirective)
.directive('hRecursive', hRecursiveDirective)
/* Demo CSS */
* { box-sizing: border-box }

html { line-height: 1.4em }

.task h4, .task h5 { margin: 0 }

.task { background-color: white }

.task.collapse {
  max-height: 1.4em;
  overflow: hidden;
}

.task.collapse h4::after {
  content: '...';
}

.task-list {
  padding: 0;
  list-style: none;
}


/* Collapse directive */
.h-collapse-expander {
  background: inherit;
  position: absolute;
  left: .5px;
  padding: 0 .2em;
}

.h-collapse-expander::before {
  content: '•';
}

.h-collapse-item {
  border-left: 1px dotted black;
  padding-left: .5em;
}

.h-collapse-wrapper {
  background: inherit;
  padding-left: .5em;
  position: relative;
}
<!DOCTYPE html>
<html>

  <head>
    <link href="collapse.css" rel="stylesheet" />
    <link href="style.css" rel="stylesheet" />
    <script data-require="angular.js@1.3.15" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js" data-semver="2.1.1" data-require="jquery@*"></script>
    <script src="script.js"></script>
    <script>
      function AppController($scope) {
        $scope.toggleCollapsed = function ($event) {
          $event.preventDefault();
          $event.stopPropagation();
          this.collapsed = !this.collapsed;
        }
        
        $scope.task = {
          name: 'All tasks',
          assignees: ['Citizens'],
          children: [
            {
              name: 'Gardening',
              assignees: ['Gardeners', 'Horticulture Students'],
              children: [
                {
                  name: 'Pull weeds',
                  assignees: ['Weeding Sub-committee']
                }
              ],
            },
            {
              name: 'Cleaning',
              assignees: ['Cleaners', 'Guests']
            }
          ]
        }
      }
      
      angular.module('app', ['h'])
      .controller('AppController', AppController)
    </script>
  </head>

  <body ng-app="app" ng-controller="AppController">
    <h1>Task Application</h1>
    
    <p>This is an AngularJS application that demonstrates a generalized
    recursive templating directive. Use it to quickly produce recursive
    structures in templates.</p>
    
    <p>The recursive directive was developed in order to avoid the need for
    recursive structures to be given their own templates and be explicitly
    self-referential, as would be required with ngInclude. Owing to its high
    priority, it should also be possible to use it for recursive directives
    (directives that have templates which include the directive) that would
    otherwise send the compiler into infinite recursion.</p>
    
    <p>The directive can be used alongside ng-if
    and ng-repeat to create recursive structures without the need for
    additional container elements.</p>
    
    <p>Since the directive does not request a scope (either isolated or not)
    it should not impair reasoning about scope visibility, which continues to
    behave as the template suggests.</p>
    
    <p>Try playing around with the demonstration, below, where the input at
    the top provides a way to modify a scope attribute. Observe how the value
    is visible at all levels.</p>
    
    <p>The collapse directive is included to further demonstrate that the
    recursion can co-exist with other transclusions (not just ngIf, et al)
    and that sibling directives are included on the recursive due to the
    recursion using whole 'element' transclusion.</p>
    
    <label for="volunteer">Citizen name:</label>
    <input id="volunteer" ng-model="you" placeholder="your name">
    <h2>Tasks</h2>
    <ul class="task-list">
      <li class="task" h-collapse h-recursive>
        <h4>{{task.name}}</h4>
        <h5>Volunteers</h5>
        <ul>
          <li ng-repeat="who in task.assignees">{{who}}</li>
          <li>{{you}} (you)</li>
        </ul>
        <ul class="task-list">
          <li h-recursive ng-repeat="task in task.children"></li>
        </ul>
      <li>
    </ul>
    
    <script type="text/ng-template" id="collapse.html">
      <div class="h-collapse-wrapper">
        <a class="h-collapse-expander" href="#" ng-click="collapse = !collapse"></a>
        <div class="h-collapse-item" ng-transclude></div>
      </div>
    </script>
  </body>

</html>


2

अब जब कि कोणीय 2.0 पूर्वावलोकन में है तो मुझे लगता है कि मिश्रण में कोणीय 2.0 विकल्प जोड़ना ठीक है। कम से कम इससे लोगों को बाद में फायदा होगा:

मुख्य अवधारणा एक आत्म संदर्भ के साथ एक पुनरावर्ती टेम्पलेट का निर्माण करना है:

<ul>
    <li *for="#dir of directories">

        <span><input type="checkbox" [checked]="dir.checked" (click)="dir.check()"    /></span> 
        <span (click)="dir.toggle()">{{ dir.name }}</span>

        <div *if="dir.expanded">
            <ul *for="#file of dir.files">
                {{file}}
            </ul>
            <tree-view [directories]="dir.directories"></tree-view>
        </div>
    </li>
</ul>

फिर आप टेम्प्लेट में एक ट्री ऑब्जेक्ट बांधते हैं और देखते हैं कि रिकर्सन बाकी का ख्याल रखता है। यहाँ एक पूर्ण उदाहरण है: http://www.syntaxsuccess.com/viewarticle/recursive-treeview-in-bularular.0


2

इसके लिए वास्तव में सरल वर्कअराउंड है जिसमें निर्देशों की आवश्यकता नहीं है।

ठीक है, इस अर्थ में, शायद यह मूल समस्या का समाधान भी नहीं है यदि आपको लगता है कि आपको निर्देशों की आवश्यकता है, लेकिन यह एक समाधान है यदि आप जीयूआई के पैरा-ड्रग उप-संरचनाओं के साथ एक पुनरावर्ती जीयूआई संरचना चाहते हैं। जो शायद आप चाहते हैं।

समाधान सिर्फ एनजी-नियंत्रक, एनजी-इनिट और एनजी-इनक्लूड का उपयोग करने पर आधारित है। बस इसे निम्नानुसार करें, मान लें कि आपके नियंत्रक को "MyController" कहा जाता है, आपका टेम्पलेट myTemplate.html में स्थित है और आपके पास अपने नियंत्रक पर एक आरंभिक फ़ंक्शन है जिसे इनिट कहा जाता है जो तर्क ए, बी और सी लेता है, जिससे यह संभव हो जाता है अपने नियंत्रक को परिमार्जित करें। तब समाधान इस प्रकार है:

myTemplate.htlm:

<div> 
    <div>Hello</div>
    <div ng-if="some-condition" ng-controller="Controller" ng-init="init(A, B, C)">
       <div ng-include="'myTemplate.html'"></div>
    </div>
</div>

मैंने सादे विश्वास से पाया कि इस तरह की संरचना को वैसा ही बनाया जा सकता है जैसा आप सादे वनीला कोणीय में पसंद करते हैं। बस इस डिजाइन पैटर्न का पालन करें और आप पुनरावर्ती यूआई-संरचनाओं का उपयोग बिना किसी उन्नत संकलन टिंकरिंग आदि के कर सकते हैं।

अपने नियंत्रक के अंदर:

$scope.init = function(A, B, C) {
   // Do something with A, B, C
   $scope.D = A + B; // D can be passed on to other controllers in myTemplate.html
} 

एकमात्र नकारात्मक पहलू जो मैं देख सकता हूं वह है क्लूनी सिंटैक्स जो आपको लगाना है।


मुझे डर है कि यह एक नहीं बल्कि मौलिक तरीके से समस्या का समाधान करने में विफल रहता हूं: इस दृष्टिकोण के साथ आप आदेश myTemplate.html में पर्याप्त नियंत्रकों के लिए में सामने प्रत्यावर्तन की गहराई जानने की आवश्यकता होगी
Stewart_R

वास्तव में, तुम नहीं। चूंकि आपकी फ़ाइल myTemplate.html में एनजी-इनका उपयोग करके myTemplate.html का स्व-संदर्भ है (ऊपर html सामग्री myTemplate.html की सामग्री है, शायद स्पष्ट रूप से नहीं बताई गई है)। इस तरह यह वास्तव में पुनरावर्ती बन जाता है। मैंने उत्पादन में तकनीक का उपयोग किया है।
इरोबवेन

इसके अलावा, शायद स्पष्ट रूप से यह नहीं कहा गया है कि आपको पुनरावृत्ति को समाप्त करने के लिए एनजी-अगर कहीं का उपयोग करने की आवश्यकता है। तो आपका myTemplate.html फ़ॉर्म तब है जैसा कि मेरी टिप्पणी में अपडेट किया गया है।
एरोबवेन

0

आप इसके लिए कोणीय-रिकर्सन-इंजेक्टर का उपयोग कर सकते हैं: https://github.com/knyga/angular-recursion-injector

आप कंडीशनिंग के साथ असीमित गहराई घोंसले के शिकार करने की अनुमति देता है। केवल आवश्यकता होने पर ही पुनर्मूल्यांकन करता है और केवल सही तत्वों का संकलन करता है। कोड में कोई जादू नहीं।

<div class="node">
  <span>{{name}}</span>

  <node--recursion recursion-if="subNode" ng-model="subNode"></node--recursion>
</div>

चीजों में से एक जो इसे तेजी से और सरल रूप से काम करने की अनुमति देती है, तो अन्य समाधान "--recursion" प्रत्यय है।


0

मैंने पुनरावृत्ति के लिए मूल निर्देशों का एक सेट तैयार किया।

IMO यह यहां पाए जाने वाले समाधान की तुलना में कहीं अधिक बुनियादी है, और अधिक लचीला है यदि अधिक नहीं, तो हम UL / LI संरचनाओं आदि का उपयोग करने के लिए बाध्य नहीं हैं ... लेकिन जाहिर है कि वे उपयोग करने के लिए समझ में आते हैं, हालांकि निर्देश इससे अनजान हैं तथ्य...

एक सुपर सरल उदाहरण होगा:

<ul dx-start-with="rootNode">
  <li ng-repeat="node in $dxPrior.nodes">
    {{ node.name }}
    <ul dx-connect="node"/>
  </li>
</ul>

'Dx-start-with' को 'dx-connect' के कार्यान्वयन में पाया जाता है: https://github.com/dotJEM/angular-tree

इसका मतलब है कि अगर आपको 8 अलग-अलग लेआउट की आवश्यकता है तो आपको 8 निर्देश नहीं बनाने होंगे।

उसके ऊपर एक ट्री-व्यू बनाने के लिए जहां आप नोड्स को जोड़ या हटा सकते हैं, फिर सरल होगा। जैसे: http://codepen.io/anon/pen/BjXGbY?editors=1010

angular
  .module('demo', ['dotjem.angular.tree'])
  .controller('AppController', function($window) {

this.rootNode = {
  name: 'root node',
  children: [{
    name: 'child'
  }]
};

this.addNode = function(parent) {
  var name = $window.prompt("Node name: ", "node name here");
  parent.children = parent.children || [];
  parent.children.push({
    name: name
  });
}

this.removeNode = function(parent, child) {
  var index = parent.children.indexOf(child);
  if (index > -1) {
    parent.children.splice(index, 1);
  }
}

  });
<div ng-app="demo" ng-controller="AppController as app">
  HELLO TREE
  <ul dx-start-with="app.rootNode">
<li><button ng-click="app.addNode($dxPrior)">Add</button></li>
<li ng-repeat="node in $dxPrior.children">
  {{ node.name }} 
  <button ng-click="app.removeNode($dxPrior, node)">Remove</button>
  <ul dx-connect="node" />
</li>
  </ul>

  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
  <script src="https://rawgit.com/dotJEM/angular-tree-bower/master/dotjem-angular-tree.min.js"></script>

</div>

इस बिंदु से, नियंत्रक और टेम्पलेट को अपने स्वयं के निर्देश में लपेटा जा सकता है अगर कोई इसके लिए चाहेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.