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


529

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

डॉक्स में, वे बताते हैं कि:

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

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

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

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




1
मैंने निर्देशन के जीवनचक्र (निर्माण चरण) के आरेख के साथ एक पोस्ट लिखा। शायद यह किसी की मदद करता है: filimanjaro.com/2014/…
औसत जो

जवाबों:


470

संकलन:

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

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

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

लिंकिंग चरण:

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

नियंत्रक:

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


67
स्पष्ट करने के लिए: संकलन पूरे पृष्ठ में उपयोग किए जाने वाले टेम्पलेट को संकलित करता है। लिंकर प्रत्येक उदाहरण से जुड़ा हुआ है। सही? नियंत्रक तो उदाहरणों के बीच काम करता है।
ज़्लातको

4
प्रत्येक निर्देश के लिए @CMCDragonkai controllerसमारोह निष्पादित किया जाता है के बाद संकलन है, लेकिन इससे पहले कि pre-link एक स्थानीय डोम पेड़ की टहनी में। इसके अलावा controllerऔर pre-linkकार्यों को टॉप-डाउन तरीके से स्थानीय डोम शाखा को पार करने के लिए निष्पादित किया जाता है। उसके बाद नीचे-ऊपर तरीके post-linkसे निष्पादित किया जाता है।
आर्टेम प्लैटोनोव

9
यह केवल एक गड़बड़ है यदि आप इसे नहीं समझते हैं। इसके लिए एक कारण है कि वह क्या करता है।
डेमक्स

3
यह सही तकनीकी जवाब है, हालांकि, मुझे अभी भी सवालों के साथ छोड़ दिया गया है जब मुझे लिंक फ़ंक्शन का उपयोग करना चाहिए।
निकोलस मार्शल

2
क्या हम हर जगह के controllerबजाय उपयोग करेंगे link? ताकि मुझे भविष्य में कोड बदलने की आवश्यकता न हो यदि विधि को साझा करने की आवश्यकता है या कुछ तर्क प्रस्तुत किए जाने की आवश्यकता है।? क्या controllerलिंक के बजाय हर समय उपयोग करने में कोई नुकसान है ?
JPS

99

मैं यह भी जोड़ना चाहता था कि Google टीम द्वारा ओ'रिली एंगुलरजेएस पुस्तक का क्या कहना है:

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

लिंक - प्रोग्रामिक रूप से संशोधित डोम तत्व उदाहरणों को संशोधित करें, घटना श्रोताओं को जोड़ें, और डेटा बाइंडिंग सेट करें।

संकलन - निर्देशात्मक रूप से जब एनजी-रिपीट में उपयोग किया जाता है, तब कॉपियों की विशेषताओं के लिए डोम टेम्पलेट को संशोधित करें। आपका संकलन फ़ंक्शन परिणामी तत्व उदाहरणों को संशोधित करने के लिए लिंक फ़ंक्शन भी वापस कर सकता है।


आपके थिंकटर.आईओ लिंक को भुगतान किए बिना नहीं देखा जा सकता है। मेरा लिंक नहीं, लेकिन शायद यह अधिक उपयुक्त है: toddmotto.com/directive-to-directive-communication-with-require
R. van Twisk

51

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

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

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

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

यदि 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समारोह।

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

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

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

1
आपने उल्लेख किया है कि आपने माता-पिता को बच्चे के नियंत्रक में कैसे प्रवेश कराया, यह दिखाया ... इस उदाहरण में बच्चे के पास नियंत्रक नहीं है, बल्कि लिंक फ़ंक्शन है ... मैं वर्तमान में इस मुद्दे पर अटक नहीं रहा हूं, इसलिए यह नहीं हो सकता है इतना महत्वपूर्ण, लेकिन एक जिज्ञासु प्रश्न।
alockwood05

13

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

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

बनाम

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

2
जब आप किसी उत्तर को छोड़ते हैं तो कृपया अपनी बात समझाने के लिए एक टिप्पणी छोड़ दें। धन्यवाद
svassr

53
मैं नीच नहीं था, लेकिन यह कड़ाई से सही नहीं है क्योंकि आप अभी भी किसी भी निर्भरता को निर्देशन में ही इंजेक्ट कर सकते हैं, जैसे module.directive('myDirective', function($window) { etc...:। इसे फिर लिंक फ़ंक्शन के अंदर से एक्सेस किया जा सकता है।
माइक चेम्बरलेन

1
यह सीधा गलत लगता है क्योंकि आप लिंक फ़ंक्शन में सेवाओं को इंजेक्ट कर सकते हैं
कोड व्हिस्परर

1
@JoshRibakoff अंतिम परिणाम समान है, आपके पास लिंक फ़ंक्शन में सेवा तक पहुंच है। इससे कोई फर्क नहीं पड़ता कि यह फ़ंक्शन के तर्कों में घोषित किया गया है या नहीं। इस संबंध में माइक चेम्बरलेन सही है
कॉनर व्याट

1
@ cwyatt1 मैं parlance को सही कर रहा था, plnkr एक लिंक () फ़ंक्शन में इंजेक्ट नहीं दिखाता है क्योंकि यह एक फ़ीचर नहीं है जो कोणीय है। आप सोच सकते हैं कि मुझे पांडित्य हो रहा है, लेकिन मेटमैट्स टिप्पणी पहले से ही कई महत्वपूर्ण अंतरों को रेखांकित करती है कि प्लंकर क्या करता है, और एक नियंत्रक को क्या करना है। ओपी पूछ रहा है कि अंतर क्या हैं, और अंतर क्या हैं।
जोश रिबाकोफ

10

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

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>

4
क्या आप इस बारे में विस्तार से बता सकते हैं कि यह नमूना कोड link, compileऔर , के बीच के अंतर को समझने में मदद क्यों करेगा controller?
cel शार्प

क्या आप जानते हैं कि कैसे एक requireडी निर्देश एक आश्रित निर्देशक के नियंत्रक में इंजेक्ट किया जा सकता है?
alockwood05

आप कोड उदाहरण: अनकैप्ड एरर: [$ इंजेक्टर: मोडुलेर] इंस्ट्रूमेंट माईएप के कारण असफल हो गया: त्रुटि: [$ इंजेक्टर: अनप्र] अज्ञात प्रदाता: slngStylePrelinkProvider
rofit

7
  • संकलन : का उपयोग तब किया जाता है जब हमें निर्देश टेम्पलेट को संशोधित करने की आवश्यकता होती है, जैसे नई अभिव्यक्ति को जोड़ना, इस निर्देश के अंदर एक और निर्देश जोड़ना
  • नियंत्रक : का उपयोग तब किया जाता है जब हमें $ स्कोप डेटा साझा / पुन: उपयोग करने की आवश्यकता होती है
  • लिंक : यह एक ऐसा फंक्शन है जिसका इस्तेमाल हमें इवेंट हैंडलर को अटैच करने या DOM में हेरफेर करने के लिए करना पड़ता है।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.