2013-07-26 12 views
6

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

समस्या तब होती है जब मैं लिंक फ़ंक्शन के अंदर element.children() विधि को कॉल करता हूं, मेरे पास एक खाली सरणी है क्योंकि ng-repeat निर्देश अभी तक प्रस्तुत नहीं किया गया है और इसे एक टिप्पणी के रूप में व्याख्या किया गया है।

अन्यथा, यदि सामग्री 'स्थिर' है तो निर्देश महान काम करता है।

एचटीएमएल

<grid n='6'> 
    <div ng-repeat="i in [1,2,3]"></div> 
</grid> 

मेरी केवल कोड के दिलचस्प टुकड़े के साथ निर्देश:

app.directive('grid', [function() { 
    return { 

     restrict: 'E', 
     replace: true, 
     transclude: true, 
     template: "<div ng-transclude></div>", 

     link: function (scope, grid, attrs) { 

      // With an ngRepeat transcluded, els result in an empty array 
      var els = grid.children(); 

      // ... 
    }; 
}]); 

मैं क्या याद आ रही है?

+2

अपने लिंक समारोह के भीतर आप $ timout (function() {// पहुँच ग्रिड बच्चों}, 0) का उपयोग कर प्रयास कर सकते हैं; – Chandermani

+0

वह वास्तव में काम करता है, लेकिन क्या यह विधि विश्वसनीय है? –

+0

असल में आप पोस्ट लिंक फ़ंक्शन के बाद बाल टेम्पलेट प्रदान करते हैं, इसलिए आपको $ टाइमआउट जोड़ने की ज़रूरत है, यह काम करेगा क्योंकि इसमें कुछ देरी शामिल है। – Chandermani

उत्तर

0

पुनर्व्यवस्था को प्राप्त करने, आप कई विकल्प हैं:

  1. हेरफेर डोम। आईएमएचओ, यह सबसे पसंदीदा तरीका है, यह बहुत कोणीय नहीं है।
  2. सरणी को पुन: क्रमबद्ध करें ([1, 2, 3]) जिसका उपयोग आपके लिंकिंग फ़ंक्शन में ngRepeat में किया जाता है।
  3. उपयोग orderBy फिल्टर (doc)

मैं प्रदर्शित करने के लिए 2 और 3, आशा है कि यह मदद कर सकता है एक खनखनाहट बना लिया है। http://plnkr.co/edit/vrgeBoJZiG6WMu4Rk46u?p=preview

+0

मैंने आपको 'रीडर' शब्द से गुमराह किया होगा। मेरा लक्ष्य तत्वों को ग्रिड के रूप में पुनर्व्यवस्थित करने के लिए अधिक था (उदाहरण के लिए 3 तत्व/पंक्ति)। आपका धन्यावाद ;) –

0

इस तक पहुंचने के कुछ तरीके हैं। सबसे आसान और सबसे आम समाधान आप देखेंगे के रूप में टिप्पणी का सुझाव है - जैसे लाभ उठाने $timeout ...

.directive('grid', ['$timeout', function ($timeout) { 
    return { 
     restrict: 'E', 
     replace: true, 
     transclude: true, 
     template: '<div ng-transclude></div>', 
     link: function (scope, grid, attrs) { 
      $timeout(function() { 
       console.log(grid.children()); 
      }); 
     } 
    } 
}]); 

$ टाइमआउट ([fn], [देरी], [invokeApply], [दर्रा]);

[...]

invokeApply - झूठे स्किप के मॉडल गंदा जाँच करने के लिए सेट करते हैं, अन्यथा $ भीतर fn लागू करेगा ब्लॉक लागू होते हैं। (डिफ़ॉल्ट: सच)

$timeout कॉलिंग एक $digest चक्र के लिए बाध्य करेगा - तो समय से आप बच्चों को लॉग इन करें - ng-repeat निर्देश हो जाएगा "हो गया।" ng-repeat के साथ दौड़ यहां समस्या का क्रूक्स है - क्योंकि जब भी हम link फ़ंक्शन दर्ज करते हैं, तब भी यह अभी भी यह काम कर रहा है।


एक और तरीका है आप इस का समाधान कर सकते हैं - जो निश्चित रूप से कम आम है - लेकिन घटनाओं की एक अधिक विस्तृत अनुक्रम को दर्शाता हुआ पर बहुत अच्छा काम करता है, इस प्रकार है ...

.directive('grid', [function() { 
    return { 
     restrict: 'E', 
     replace: true, 
     transclude: true, 
     template: '<div ng-transclude></div>', 
     link: function (scope, grid, attrs) { 
      scope.$on('repeat-done', function() { 
       console.log(grid.children()); 
      }); 
     } 
    } 
}]) 
.directive('ngRepeat', [function() { 
    return { 
     restrict: 'A', 
     link: function (scope, elem, attrs) { 
      if (scope.$last) 
       scope.$root.$broadcast('repeat-done'); 
     } 
    }; 
}]); 

यहाँ हम कर रहे हैं निष्पादन पर एक समारोह का आह्वान करने के लिए ng-repeat को अविश्वसनीय रूप से विस्तारित करना - और हम फ़ंक्शन में $on के माध्यम से इसकी सदस्यता ले सकते हैं।


JSFiddle Link - सरल डेमो प्रदर्शन दोनों दृष्टिकोण

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

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