angularjs - लिंक बनाम संकलन बनाम नियंत्रक




angularjs-directive (4)

इसके अलावा, नियंत्रक बनाम लिंक फ़ंक्शन का उपयोग करने का एक अच्छा कारण (क्योंकि दोनों के पास दायरे, तत्व और attrs तक पहुंच है) क्योंकि आप किसी भी उपलब्ध सेवा या निर्भरता में नियंत्रक (और किसी भी क्रम में) में गुजर सकते हैं, जबकि आप लिंक फ़ंक्शन के साथ ऐसा नहीं कर सकते हैं। विभिन्न हस्ताक्षरों पर ध्यान दें:

controller: function($scope, $exceptionHandler, $attr, $element, $parse, $myOtherService, someCrazyDependency) {...

बनाम

link: function(scope, element, attrs) {... //no services allowed

जब आप निर्देश बनाते हैं, तो आप संकलक, लिंक फ़ंक्शन या नियंत्रक में कोड डाल सकते हैं।

दस्तावेज़ों में, वे समझाते हैं कि:

  • संकलन और लिंक फ़ंक्शन कोणीय चक्र के विभिन्न चरणों में उपयोग किया जाता है
  • नियंत्रकों को निर्देशों के बीच साझा किया जाता है

हालांकि, मेरे लिए यह स्पष्ट नहीं है कि किस प्रकार का कोड जाना चाहिए।

उदाहरण: क्या मैं संकलन में फ़ंक्शंस बना सकता हूं और उन्हें लिंक में दायरे से जोड़ सकता हूं या केवल नियंत्रक में दायरे में फ़ंक्शंस संलग्न कर सकता हूं?

निर्देशकों के बीच नियंत्रक कैसे साझा किए जाते हैं, यदि प्रत्येक निर्देश का अपना नियंत्रक हो सकता है? क्या नियंत्रक वास्तव में साझा हैं या क्या यह केवल दायरे के गुण हैं?


एक directive आपको वेब घटकों के निर्माण के लिए घोषणात्मक फैशन में HTML शब्दावली का विस्तार करने की अनुमति देता है। ng-app विशेषता एक निर्देश है, इसलिए ng-controller और सभी ng-controller ng- prefixed attributes । निर्देश attributes , tags या यहां तक ​​कि class names , comments

निर्देश कैसे पैदा होते हैं ( compilation और instantiation )

संकलन: हम इसे प्रस्तुत करने से पहले डीओएम में manipulate करने के लिए compile फ़ंक्शन का उपयोग करेंगे और एक link फ़ंक्शन लौटाएंगे (जो हमारे लिए लिंकिंग को संभालेगा)। यह भी उन तरीकों को रखने का स्थान है जिन्हें इस निर्देश के सभी instances के साथ साझा करने की आवश्यकता है।

लिंक: हम सभी श्रोताओं को एक विशिष्ट DOM तत्व (जिसे टेम्पलेट से क्लोन किया गया है) पर पंजीकृत करने के लिए link फ़ंक्शन का उपयोग करेंगे और पृष्ठ पर हमारी बाइंडिंग सेट अप करेंगे।

यदि compile() फ़ंक्शन में सेट किया गया है तो वे केवल एक बार सेट किए जाएंगे (जो अक्सर आप चाहते हैं)। यदि link() फ़ंक्शन में सेट किया गया है तो वे प्रत्येक बार HTML तत्व डेटा में बाध्य होने पर सेट किए जाएंगे वस्तु।

<div ng-repeat="i in [0,1,2]">
    <simple>
        <div>Inner content</div>
    </simple>
</div>

app.directive("simple", function(){
   return {
     restrict: "EA",
     transclude:true,
     template:"<div>{{label}}<div ng-transclude></div></div>",        
     compile: function(element, attributes){  
     return {
             pre: function(scope, element, attributes, controller, transcludeFn){

             },
             post: function(scope, element, attributes, controller, transcludeFn){

             }
         }
     },
     controller: function($scope){

     }
   };
});

Compile समारोह pre और post लिंक समारोह देता है। प्री लिंक फ़ंक्शन में हमारे पास इंस्टेंस टेम्पलेट और controller से दायरा भी है, लेकिन फिर भी टेम्पलेट गुंजाइश नहीं है और अभी भी स्थानांतरित सामग्री नहीं है।

Post लिंक फ़ंक्शन वह है जहां पोस्ट लिंक निष्पादित करने के लिए अंतिम कार्य है। अब transclusion पूरा हो गया है, the template is linked to a scope , और view will update with data bound values after the next digest cyclelink विकल्प एक post-link फ़ंक्शन सेट अप करने के लिए केवल एक शॉर्टकट है।

नियंत्रक: निर्देशक नियंत्रक को दूसरे निर्देश जोड़ने / संकलन चरण में पारित किया जा सकता है। इसे अन्य निर्देशों में अंतर-निर्देश संचार में उपयोग करने के साधन के रूप में इंजेक्शन दिया जा सकता है।

आपको आवश्यक निर्देश का नाम निर्दिष्ट करना होगा - यह उसी तत्व या उसके माता-पिता से बंधे होना चाहिए। नाम के साथ prefixed किया जा सकता है:

? – Will not raise any error if a mentioned directive does not exist.
^ – Will look for the directive on parent elements, if not available on the same element.

एकाधिक निर्देश नियंत्रक की आवश्यकता के लिए स्क्वायर ब्रैकेट ['directive1′, 'directive2′, 'directive3′] करें।

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

app.controller('MainCtrl', function($scope, $element) {
});

app.directive('parentDirective', function() {
  return {
    restrict: 'E',
    template: '<child-directive></child-directive>',
    controller: function($scope, $element){
      this.variable = "Hi Vinothbabu"
    }
  }
});

app.directive('childDirective', function() {
  return {
    restrict:  'E',
    template: '<h1>I am child</h1>',
    replace: true,
    require: '^parentDirective',
    link: function($scope, $element, attr, parentDirectCtrl){
      //you now have access to parentDirectCtrl.variable
    }
  }
});

यह निर्देश चरणों को समझने के लिए एक अच्छा नमूना है http://codepen.io/anon/pen/oXMdBQ?editors=101

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

app.directive('slngStylePrelink', function() {
    return {
        scope: {
            drctvName: '@'
        },
        controller: function($scope) {
            console.log('controller for ', $scope.drctvName);
        },
        compile: function(element, attr) {
            console.log("compile for ", attr.name)
            return {
                post: function($scope, element, attr) {
                    console.log('post link for ', attr.name)
                },
                pre: function($scope, element, attr) {
                    $scope.element = element;
                    console.log('pre link for ', attr.name)
                        // from angular.js 1.4.1
                    function ngStyleWatchAction(newStyles, oldStyles) {
                        if (oldStyles && (newStyles !== oldStyles)) {
                            forEach(oldStyles, function(val, style) {
                                element.css(style, '');
                            });
                        }
                        if (newStyles) element.css(newStyles);
                    }

                    $scope.$watch(attr.slngStylePrelink, ngStyleWatchAction, true);

                    // Run immediately, because the watcher's first run is async
                    ngStyleWatchAction($scope.$eval(attr.slngStylePrelink));
                }
            };
        }
    };
});

एचटीएमएल

<body ng-app="myapp">
    <div slng-style-prelink="{height:'500px'}" drctv-name='parent' style="border:1px solid" name="parent">
        <div slng-style-prelink="{height:'50%'}" drctv-name='child' style="border:1px solid red" name='child'>
        </div>
    </div>
</body>

संकलन:

यह वह चरण है जहां कोणीय वास्तव में आपके निर्देश को संकलित करता है। दिए गए निर्देश के प्रत्येक संदर्भ के लिए यह संकलन फ़ंक्शन केवल एक बार कहा जाता है। उदाहरण के लिए, कहें कि आप एनजी-दोहराव निर्देश का उपयोग कर रहे हैं। ng-repeat को उस तत्व को देखना होगा जिसे वह संलग्न किया गया है, एचटीएमएल खंड को निकालें जो इसे संलग्न करता है और टेम्पलेट फ़ंक्शन बनाता है।

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

संकलन चरण वह कोणीय में चरण है जो टेम्पलेट फ़ंक्शन देता है। कोणीय में यह टेम्पलेट फ़ंक्शन लिंकिंग फ़ंक्शन कहा जाता है।

लिंकिंग चरण:

लिंकिंग चरण वह है जहां आप लिंकिंग फ़ंक्शन पर डेटा ($ स्कोप) संलग्न करते हैं और इसे आपको लिंक किए गए HTML को वापस करना चाहिए। चूंकि निर्देश यह भी निर्दिष्ट करता है कि यह एचटीएमएल कहां जाता है या यह क्या बदलता है, यह पहले से ही अच्छा है। यह वह कार्य है जहां आप लिंक किए गए एचटीएमएल में परिवर्तन करना चाहते हैं, यानि एचटीएमएल जिसमें पहले से ही डेटा संलग्न है। कोणीय में यदि आप लिंकिंग फ़ंक्शन में कोड लिखते हैं तो आम तौर पर पोस्ट-लिंक फ़ंक्शन (डिफ़ॉल्ट रूप से)। यह एक कॉलबैक है जिसे लिंकिंग फ़ंक्शन ने टेम्पलेट के साथ डेटा को लिंक करने के बाद बुलाया है।

नियंत्रक:

नियंत्रक एक ऐसा स्थान है जहां आप कुछ निर्देश विशिष्ट तर्क में डालते हैं। यह तर्क लिंकिंग फ़ंक्शन में भी जा सकता है, लेकिन फिर आपको उस तर्क को "साझा करने योग्य" बनाने के लिए दायरे पर रखना होगा। इसके साथ समस्या यह है कि आप अपने निर्देशों के सामान के साथ दायरे को भ्रष्ट कर देंगे जो वास्तव में कुछ ऐसा नहीं है जो अपेक्षित है। तो क्या विकल्प है यदि दो निर्देश एक-दूसरे से बात करना चाहते हैं / एक-दूसरे के साथ सह-संचालन करना चाहते हैं? चिंता है कि आप उस तर्क को एक सेवा में डाल सकते हैं और फिर इन दोनों निर्देशों को उस सेवा पर निर्भर करते हैं, लेकिन यह केवल एक और निर्भरता लाता है। विकल्प इस दायरे के लिए नियंत्रक प्रदान करना है (आमतौर पर गुंजाइश अलग करना?) और फिर इस नियंत्रक को किसी अन्य निर्देश में इंजेक्शन दिया जाता है जब उस निर्देश को दूसरे की आवश्यकता होती है। उदाहरण के लिए angularjs.org के पहले पृष्ठ पर टैब और पैन देखें।





angularjs-directive