2015-01-14 29 views
7

में नए संस्थाओं से दिखाई नहीं दे जो एक निर्देशिका/नेस्ट वृक्ष संरचना के निर्माण के लिए एक सुविधा शामिल है एक कोणीय एप्लिकेशन का विकास ...कोणीय नेस्टेड निर्देश मॉडल

मुद्दा मैं आ रही हैं नोड्स के प्रतिपादन काफी नहीं है इरादे के रूप में काम कर रहे हैं।

उत्पाद केवल तभी प्रस्तुत किए जाते हैं जब सूची में पहले से ही कोई उत्पाद नोड होता है और अनुभाग बनाए जा सकते हैं लेकिन जोड़े गए एक को उपधारा जोड़ने का प्रयास नहीं किया जाता है। अनुभाग और उत्पाद नोड्स को मॉडल में अपेक्षित रूप से डाला जा रहा है - बस यह कि निर्देश मूल मॉडल में मौजूद नोड्स पर काम नहीं कर रहे हैं।

प्रासंगिक कोड:

एचटीएमएल

<head> 
    <meta charset="utf-8" /> 
    <title>AngularJS Plunker</title> 
    <script>document.write('<base href="' + document.location + '" />');</script> 
    <link rel="stylesheet" href="style.css" /> 
    <script data-require="[email protected]" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.7/angular.js" data-semver="1.3.7"></script> 
    <script src="app.js"></script> 
</head> 

<body ng-controller="MainCtrl"> 
    <h1>Menu</h1> 
    <button ng-click="addSection()">Add</button> 
    <admin-sections sections="menu.sections"></admin-sections> 
</body> 

</html> 

जे एस

var app = angular.module('plunker', []); 

app.controller('MainCtrl', function($scope) { 
    $scope.menu = { 
    sections: [{ 
     name: "NEW SECTION 1", 
     sections: [{ 
     name: "NEW SECTION", 
     sections: [], 
     products: [{ 
      "name": "Product", 
      "price": "0.00" 
     }] 
     }], 
     products: [] 
    }] 
    }; 

    $scope.addSection = function() { 
    $scope.menu.sections.push({ 
     name: "NEW SECTION", 
     sections: [], 
     products: [] 
    }); 
    }; 
}); 

app 
    .directive('adminSections', function() { 
    return { 
     restrict: "E", 
     replace: true, 
     scope: { 
     sections: '=' 
     }, 
     templateUrl: 'sections.html' 
    }; 
    }) 
    .directive('adminSection', function($compile) { 
    return { 
     restrict: "E", 
     replace: true, 
     scope: { 
     section: '=' 
     }, 
     templateUrl: 'section.html', 

     link: function(scope, element, attrs, controller) { 
     if (angular.isArray(scope.section.sections) && scope.section.sections.length > 0) { 
      element.append($compile('<admin-sections sections="section.sections"></admin-sections>')(scope)); 
     } 
     if (angular.isArray(scope.section.products) && scope.section.products.length > 0) { 
      element.append($compile('<admin-products products="section.products"></admin-products>')(scope)); 
     } 

     scope.addSub = function(section) { 
      section.sections.push({ 
      "name": "NEW SECTION", 
      "sections": [], 
      "products": [] 
      }); 
     }; 

     scope.addProduct = function(section) { 
      section.products.push({ 
      "name": "Product", 
      "price": "0.00" 
      }); 
     }; 

     scope.deleteSection = function(section) { 
      var idx = scope.$parent.sections.indexOf(section); 
      scope.$parent.sections.splice(idx, 1); 
     }; 
     } 
    }; 
    }) 
    .directive('adminProducts', function() { 
    return { 
     restrict: "E", 
     replace: true, 
     scope: { 
     products: '=' 
     }, 
     templateUrl: 'products.html', 
     link: function(scope, element, attrs, controller) { 
     scope.editProduct = function(product) { 
      if (product.price === undefined) { 
      product.price = 0; 
      } 
      element.append($compile('<productform product="product"></productform>')(scope)); 
     }; 

     scope.deleteProduct = function(idx) { 
      if (confirm('Are you sure you want to delete this product?\n\nClick OK to confirm.')) { 
      scope.products.splice(idx, 1); 
      } 
     }; 
     } 
    }; 
    }) 
    .directive('adminProduct', function($compile) { 
    return { 
     restrict: "E", 
     replace: true, 
     scope: { 
     product: '=' 
     }, 
     templateUrl: 'product.html', 
     link: function(scope, element, attr, controller) { 

     scope.editProduct = function(product) { 
      if (product.price === undefined) { 
      product.price = 0; 
      } 
      element.append($compile('<productform product="product" />')(scope)); 
     }; 

     scope.deleteProduct = function(idx) { 
      scope.$parent.deleteProduct(idx); 
     }; 
     } 
    }; 
    }) 
    .directive('productform', function($compile) { 
    return { 
     restrict: "E", 
     replace: true, 
     scope: { 
     product: "=" 
     }, 
     templateUrl: 'productform.html', 
     link: function(scope, element, attrs, controller) { 
     scope.orig = angular.copy(scope.product); 
     scope.ok = function() { 
      element.remove(); 
      scope.$parent.editMode = false; 
     }; 

     scope.cancel = function() { 
      scope.reset(); 
      element.remove(); 
      scope.$parent.editMode = false; 
     } 

     scope.reset = function() { 
      scope.product = angular.copy(scope.orig); 
     } 
     } 
    }; 
    }); 

Plunker यहाँ है: Angular Tree Menu

उम्मीद है कि आप आशय देख सकते हैं।

उत्तर

3

समस्या यह है कि जब आप लिंकिंग फ़ंक्शन कहलाते हैं तो अनुभाग के राज्य के आधार पर निर्देश जोड़ने पर सूची जोड़ती है (केवल एक बार, जब कोणीय इसे देखता है)।

जब आप कोई नया उपखंड जोड़ते हैं, तो यह लिंक होता है लेकिन इसकी उपखंड सूची खाली होती है, इसलिए इसका कोई उपखंड नहीं होता है, और परिणामी तत्व में कोई उपखंड नहीं होता है, क्योंकि जब आप लिंकिंग फ़ंक्शन होता है तो उपखंड क्रिया स्थिति के आधार पर admin-sections जोड़ते हैं कहा जाता है, इसलिए कोई भी घोंसला निर्देश नहीं जोड़ा जाएगा।

आप को दूर करने if बयान (अगर वे सरणियों हैं या बस) पर्याप्त होना चाहिए:

element.append($compile('<admin-sections sections="section.sections"></admin-sections>')(scope)); 

element.append($compile('<admin-products products="section.products"></admin-products>')(scope)); 

इस तरह, ng-repeat अपने निर्देशों में प्रत्येक अनुभाग में वर्गों सरणियों देख सकते हैं और तदनुसार सूची अपडेट करेगा, सरणी खाली होने पर खाली रहती है।

Working Plunker


कैसे नेस्टेड निर्देशों काम करते हैं, यहाँ एक अच्छा article जब नेस्ट निर्देशों 'जोड़ने और नियंत्रक कार्यों कहा जाता है पर है के रूप में।

सामान्य रूप से, controller एस किसी भी आंतरिक निर्देशों को पार्स किए जाने से पहले चलाए जाते हैं, और link एस के बाद चलाए जाते हैं।तो अगर आप इस तरह के निर्देशों नेस्ट किया है:

<outer-directive> 
    <inner-directive></inner-directive> 
</outer-directive> 

क्रम इस तरह होगा:

  1. बाहरी-निर्देश नियंत्रक
  2. भीतरी निर्देश नियंत्रक
  3. भीतरी निर्देश लिंक
  4. बाहरी निर्देशक लिंक

यह मैं क्यों मैंने प्रत्येक अनुभाग के टेम्पलेट में admin-sections निर्देश जोड़ने का प्रयास किया, तो पार्सर एक अनंत लूप में चला गया। प्रत्येक खंड को पार्स करने के लिए उस अनुभाग के उपखंडों के link को कॉल करना था, लेकिन बाहरी admin-section के लिंकिंग फ़ंक्शन में $compile का उपयोग करने का अर्थ है बाहरी निर्देश संसाधित होने के बाद इसे पार्स किया जाएगा।

इसके अतिरिक्त, आंतरिक निर्देश require (docs) अपने नियंत्रकों का उपयोग करने के लिए मूल निर्देशों को कर सकते हैं।

+0

किंवदंती - मैंने वास्तव में बटरंग को हटा दिया क्योंकि यह मेरे कोड को काम करने से रोकने के लिए प्रतीत होता है - हटाने के लिए कुछ अपेक्षित व्यवहार होने की अनुमति है, लेकिन मुझे संदेह है कि अनंत लूप वास्तविक कारण था ... बहुत बहुत धन्यवाद - मुझे यकीन था कि यह कुछ था बाइंडिंग/वॉचर्स कैसे काम करते हैं, इस बारे में सरल और थोड़ी सी समझ में कुछ स्पष्ट रूप से कमी आई थी। –

संबंधित मुद्दे