AngularJS में निर्देशक दायरे में '@' और '=' के बीच क्या अंतर है?




angularjs-directive angularjs-scope (10)

मैंने विषय पर AngularJS दस्तावेज़ को ध्यान से पढ़ा है, और फिर निर्देश के साथ चारों ओर झुका हुआ है। यहाँ fiddle

और यहां कुछ प्रासंगिक स्निपेट हैं:

  • एचटीएमएल से:

    <pane bi-title="title" title="{{title}}">{{text}}</pane>
    
  • फलक निर्देश से:

    scope: { biTitle: '=', title: '@', bar: '=' },
    

ऐसी कई चीजें हैं जो मुझे नहीं मिलती हैं:

  • मुझे "{{title}}" साथ '@' और "title" साथ '=' का उपयोग क्यों करना है?
  • क्या मैं एक विशेषता के साथ अपने तत्व को सजाने के बिना सीधे माता-पिता के दायरे तक पहुंच सकता हूं?
  • दस्तावेज़ीकरण कहता है, "अक्सर अभिव्यक्ति के माध्यम से और अभिभावक के दायरे से पृथक गुंजाइश से डेटा पास करना वांछनीय है" , लेकिन यह भी द्विपक्षीय बाध्यकारी के साथ ठीक काम करता प्रतीत होता है। अभिव्यक्ति मार्ग बेहतर क्यों होगा?

मुझे एक और पहेली मिली जो अभिव्यक्ति समाधान को भी दिखाती है: http://jsfiddle.net/maxisam/QrCXh/


मुझे '{{title}} "के साथ' @ 'और" शीर्षक "के साथ' = 'का उपयोग क्यों करना है?

@ डीओएम विशेषता के मूल्यांकन मूल्य पर स्थानीय / निर्देशक स्कोप संपत्ति को बांधता है। यदि आप title=title1 या title="title1" , तो DOM विशेषता "शीर्षक" का मान केवल स्ट्रिंग title1 । यदि आप title="{{title}}" , तो DOM विशेषता "शीर्षक" का मान {{title}} का इंटरपोलेटेड मान है, इसलिए स्ट्रिंग जो भी मूल दायरा संपत्ति "शीर्षक" सेट हो जाएगी। चूंकि विशेषता मान हमेशा स्ट्रिंग होते हैं, इसलिए आप @ @ का उपयोग करते समय निर्देश के दायरे में इस संपत्ति के लिए स्ट्रिंग मान के साथ हमेशा समाप्त हो जाएंगे।

= एक स्थानीय दायरे की संपत्ति के लिए एक स्थानीय / निर्देश स्कोप संपत्ति बांधता है। तो = के साथ, आप माता-पिता मॉडल / स्कोप प्रॉपर्टी नाम का उपयोग DOM विशेषता के मान के रूप में करते हैं। आप {{}} s के साथ = का उपयोग नहीं कर सकते हैं।

@ के साथ, आप title="{{title}} and then some" जैसी चीजें कर सकते हैं title="{{title}} and then some" - {{title}} को अलग किया जाता है, फिर स्ट्रिंग "और उन्हें कुछ" इसके साथ संयोजित किया जाता है। अंतिम समेकित स्ट्रिंग वह है जो स्थानीय / निर्देशक स्कोप संपत्ति प्राप्त करती है। (आप इसे = , केवल @ के साथ नहीं कर सकते हैं।)

@ के साथ, यदि आपको अपने लिंक (आईएनजी) फ़ंक्शन में मान का उपयोग करने की आवश्यकता है, तो आपको attr.$observe('title', function(value) { ... }) का उपयोग करने की आवश्यकता होगी। उदाहरण के लिए, if(scope.title == "...") आपकी अपेक्षा की तरह काम नहीं करेगा। ध्यान दें कि इसका मतलब है कि आप केवल इस विशेषता को asynchronously एक्सेस कर सकते हैं। यदि आप केवल टेम्पलेट में मान का उपयोग कर रहे हैं तो आपको $ निरीक्षण () का उपयोग करने की आवश्यकता नहीं है। उदाहरण के लिए, template: '<div>{{title}}</div>'

= के साथ, आपको $ निरीक्षण का उपयोग करने की आवश्यकता नहीं है।

क्या मैं एक विशेषता के साथ अपने तत्व को सजाने के बिना सीधे माता-पिता के दायरे तक पहुंच सकता हूं?

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

scope: { ... }

और फिर आपका निर्देश एक नया दायरा नहीं बनाएगा। यह मूल दायरे का उपयोग करेगा। फिर आप सीधे सभी मूल दायरे गुणों तक पहुंच सकते हैं।

दस्तावेज़ीकरण कहता है, "अक्सर अभिव्यक्ति के माध्यम से और अभिभावक के दायरे से पृथक गुंजाइश से डेटा पास करना वांछनीय है", लेकिन यह भी द्विपक्षीय बाध्यकारी के साथ ठीक काम करता प्रतीत होता है। अभिव्यक्ति मार्ग बेहतर क्यों होगा?

हां, बिडरेक्शनल बाध्यकारी स्थानीय / निर्देशक दायरे और डेटा साझा करने के लिए मूल दायरे की अनुमति देता है। "अभिव्यक्ति बाध्यकारी" निर्देश को एक DOM विशेषता द्वारा परिभाषित अभिव्यक्ति (या फ़ंक्शन) को कॉल करने की अनुमति देता है - और आप अभिव्यक्ति या फ़ंक्शन के लिए तर्क के रूप में डेटा भी पास कर सकते हैं। इसलिए, यदि आपको माता-पिता के साथ डेटा साझा करने की आवश्यकता नहीं है - तो आप केवल मूल दायरे में परिभाषित फ़ंक्शन को कॉल करना चाहते हैं - आप & वाक्यविन्यास का उपयोग कर सकते हैं।

यह भी देखें


मुझे '{{title}} "के साथ' @ 'और" शीर्षक "के साथ' = 'का उपयोग क्यों करना है?

जब आप {{title}} का उपयोग करते हैं, तो केवल अभिभावक स्कोप मान निर्देशक दृश्य और मूल्यांकन के लिए पारित किया जाएगा। यह एक तरफ तक सीमित है, जिसका अर्थ है कि परिवर्तन माता-पिता के दायरे में दिखाई नहीं देगा। जब आप माता-पिता के दायरे में किए गए परिवर्तनों को प्रतिबिंबित करना चाहते हैं तो आप '=' का उपयोग कर सकते हैं। यह दो तरह का है।

क्या मैं एक विशेषता के साथ अपने तत्व को सजाने के बिना सीधे माता-पिता के दायरे तक पहुंच सकता हूं?

जब निर्देश में स्कोप विशेषता होती है (दायरा: {}), तो आप अब सीधे माता-पिता के दायरे तक पहुंचने में सक्षम नहीं होंगे। लेकिन फिर भी इसे दायरे के माध्यम से एक्सेस करना संभव है। $ माता-पिता इत्यादि। यदि आप निर्देश से दायरे को हटाते हैं, तो इसे सीधे एक्सेस किया जा सकता है।

दस्तावेज़ीकरण कहता है, "अक्सर अभिव्यक्ति के माध्यम से और अभिभावक के दायरे से पृथक गुंजाइश से डेटा पास करना वांछनीय है", लेकिन यह भी द्विपक्षीय बाध्यकारी के साथ ठीक काम करता प्रतीत होता है। अभिव्यक्ति मार्ग बेहतर क्यों होगा?

यह संदर्भ के आधार पर निर्भर करता है। यदि आप डेटा के साथ एक अभिव्यक्ति या फ़ंक्शन को कॉल करना चाहते हैं, तो आप और यदि आप डेटा साझा करना चाहते हैं, तो आप '=' का उपयोग करके बाध्यकारी तरीके का उपयोग कर सकते हैं

आप नीचे दिए गए लिंक पर निर्देश देने के लिए डेटा पास करने के कई तरीकों के बीच अंतर पा सकते हैं:

AngularJS - पृथक Scopes - @ बनाम = बनाम &

http://www.codeforeach.com/angularjs/angularjs-isolated-scopes-vs-vs


निर्देश में तीन तरीकों का दायरा जोड़ा जा सकता है:

  1. अभिभावक दायरा : यह डिफ़ॉल्ट दायरा विरासत है।

निर्देश और उसके माता-पिता (नियंत्रक / निर्देश जिसमें यह झूठ है) गुंजाइश समान है। तो निर्देश के अंदर दायरे चर के लिए किए गए कोई भी परिवर्तन माता-पिता नियंत्रक में भी दिखाई देते हैं। आपको इसे निर्दिष्ट करने की आवश्यकता नहीं है क्योंकि यह डिफ़ॉल्ट है।

  1. बाल दायरा : निर्देश एक बच्चे के दायरे को बनाता है जो माता-पिता के दायरे से प्राप्त होता है यदि आप निर्देश के दायरे चर को सत्य के रूप में निर्दिष्ट करते हैं।

यहां, यदि आप निर्देश के अंदर स्कोप चर बदलते हैं, तो यह मूल दायरे में प्रतिबिंबित नहीं होगा, लेकिन यदि आप एक स्कोप चर की संपत्ति बदलते हैं, जो मूल दायरे में दिखाई देता है, जैसा कि आपने वास्तव में माता-पिता के दायरे चर को संशोधित किया है ।

उदाहरण,

app.directive("myDirective", function(){

    return {
        restrict: "EA",
        scope: true,
        link: function(element, scope, attrs){
            scope.somvar = "new value"; //doesnot reflect in the parent scope
            scope.someObj.someProp = "new value"; //reflects as someObj is of parent, we modified that but did not override.
        }
    };
});
  1. पृथक गुंजाइश : इसका उपयोग तब किया जाता है जब आप उस दायरे को बनाना चाहते हैं जो नियंत्रक दायरे से प्राप्त नहीं होता है।

ऐसा तब होता है जब आप प्लगइन बना रहे होते हैं क्योंकि इससे निर्देश सामान्य होता है क्योंकि इसे किसी भी HTML में रखा जा सकता है और इसके मूल दायरे से प्रभावित नहीं होता है।

अब, यदि आप मूल दायरे के साथ कोई बातचीत नहीं करना चाहते हैं, तो आप केवल खाली वस्तु के रूप में स्कोप निर्दिष्ट कर सकते हैं। पसंद,

scope: {} //this does not interact with the parent scope in any way

अधिकतर यह मामला नहीं है क्योंकि हमें माता-पिता के दायरे के साथ कुछ बातचीत की आवश्यकता है, इसलिए हम कुछ मान / परिवर्तनों को पारित करना चाहते हैं। इस कारण से, हम इसका उपयोग करते हैं:

1. "@"   (  Text binding / one-way binding )
2. "="   ( Direct model binding / two-way binding )
3. "&"   ( Behaviour binding / Method binding  )

@ का मतलब है कि नियंत्रक के दायरे में परिवर्तन निर्देशक दायरे में दिखाई देंगे, लेकिन यदि आप निर्देश दायरे में मान संशोधित करते हैं, तो नियंत्रक स्कोप चर प्रभावित नहीं होगा।

@ हमेशा मैप किए गए गुण को अभिव्यक्ति होने की अपेक्षा करता है। यह बहुत महत्वपूर्ण है; क्योंकि "@" उपसर्ग कार्य करने के लिए, हमें {{}} के अंदर विशेषता मान को लपेटने की आवश्यकता है।

= बिडरेक्शनल है इसलिए यदि आप डायरेक्टिव स्कोप में चर बदलते हैं, तो कंट्रोलर स्कोप वैरिएबल भी प्रभावित हो जाता है

और नियंत्रक स्कोप विधि को बांधने के लिए प्रयोग किया जाता है ताकि यदि आवश्यक हो तो हम इसे निर्देश से बुला सकते हैं

यहां लाभ यह है कि परिवर्तनीय का नाम नियंत्रक दायरे और निर्देशक दायरे में समान नहीं होना चाहिए।

उदाहरण, निर्देश स्कोप में एक चर "dirvar" है जो नियंत्रक दायरे के परिवर्तनीय "contVar" के साथ समन्वयित करता है। यह निर्देश के लिए बहुत सारी शक्ति और सामान्यीकरण देता है क्योंकि एक नियंत्रक वैरिएबल v1 के साथ सिंक कर सकता है जबकि एक ही नियंत्रक एक ही निर्देश का उपयोग करके द्वारवार को वैरिएबल v2 के साथ सिंक करने के लिए कह सकता है।

नीचे उपयोग का उदाहरण है:

निर्देश और नियंत्रक हैं:

 var app = angular.module("app", []);
 app.controller("MainCtrl", function( $scope ){
    $scope.name = "Harry";
    $scope.color = "#333333";
    $scope.reverseName = function(){
     $scope.name = $scope.name.split("").reverse().join("");
    };
    $scope.randomColor = function(){
        $scope.color = '#'+Math.floor(Math.random()*16777215).toString(16);
    };
});
app.directive("myDirective", function(){
    return {
        restrict: "EA",
        scope: {
            name: "@",
            color: "=",
            reverse: "&"
        },
        link: function(element, scope, attrs){
           //do something like
           $scope.reverse(); 
          //calling the controllers function
        }
    };
});

और एचटीएमएल (@ और = के लिए भिन्नता नोट करें):

<div my-directive
  class="directive"
  name="{{name}}"
  reverse="reverseName()"
  color="color" >
</div>

यहां ब्लॉग का एक link है जो इसे अच्छी तरह से वर्णन करता है।


बस हम इसका उपयोग कर सकते हैं: -

  1. @ : - एक तरफ डेटा बाध्यकारी के लिए स्ट्रिंग मानों के लिए। एक तरफ डेटा बाध्यकारी आप केवल निर्देश के लिए दायरा मूल्य पास कर सकते हैं

  2. = : - ऑब्जेक्ट वैल्यू के लिए दो तरह के डेटा बाइंडिंग के लिए। डेटा बाध्यकारी के दो तरीकों से आप निर्देश में दायरे के मूल्य के साथ-साथ एचटीएमएल में भी बदल सकते हैं।

  3. और : - विधियों और कार्यों के लिए।

संपादित करें

कोणीय संस्करण 1.5 और ऊपर के लिए हमारे घटक परिभाषा में
चार अलग-अलग प्रकार की बाइंडिंग हैं:

  1. = दो-तरफा डेटा बाध्यकारी : - यदि हम मान बदलते हैं, तो यह स्वचालित रूप से अपडेट हो जाता है
  2. < एक तरफ बाध्यकारी : - जब हम केवल माता-पिता के दायरे से पैरामीटर पढ़ना चाहते हैं और इसे अपडेट नहीं करना चाहते हैं।

  3. @ यह स्ट्रिंग पैरामीटर्स के लिए है

  4. & यह कॉलबैक के लिए है यदि आपके घटक को अपने मूल दायरे में कुछ आउटपुट करने की आवश्यकता है


मैंने एक पहेली में सभी संभावित विकल्पों को लागू किया।

यह सभी विकल्पों से संबंधित है:

scope:{
    name:'&'
},

scope:{
    name:'='
},

scope:{
    name:'@'
},

scope:{

},

scope:true,

https://jsfiddle.net/rishulmatta/v7xf2ujm


यदि आप यह देखना चाहते हैं कि यह लाइव उदाहरण के साथ कैसे काम करता है। http://jsfiddle.net/juanmendez/k6chmnch/

var app = angular.module('app', []);
app.controller("myController", function ($scope) {
    $scope.title = "binding";
});
app.directive("jmFind", function () {
    return {
        replace: true,
        restrict: 'C',
        transclude: true,
        scope: {
            title1: "=",
            title2: "@"
        },
        template: "<div><p>{{title1}} {{title2}}</p></div>"
    };
});

यहां बहुत सारे महान उत्तर हैं, लेकिन मैं अपने परिप्रेक्ष्य को @ , = , और बाध्यकारी के बीच अंतरों पर प्रस्तुत करना चाहता हूं जो मेरे लिए उपयोगी साबित हुए।

सभी तीन बाइंडिंग तत्वों के गुणों के माध्यम से आपके निर्देशक के अलग-अलग दायरे में आपके मूल दायरे से डेटा पास करने के तरीके हैं:

  1. @ बाध्यकारी तार पारित करने के लिए है। ये स्ट्रिंग इंटरपोलेटेड मानों के लिए {{}} अभिव्यक्ति का समर्थन करते हैं। उदाहरण के लिए: । इंटरपोलेटेड अभिव्यक्ति का मूल्यांकन निर्देशक के मूल दायरे के खिलाफ किया जाता है।

  2. = बाध्यकारी दो-तरफा मॉडल बाध्यकारी के लिए है। पैरेंट स्कोप में मॉडल निर्देश के अलग-अलग दायरे में मॉडल से जुड़ा हुआ है। एक मॉडल में परिवर्तन दूसरे को प्रभावित करता है, और इसके विपरीत।

  3. और बाध्यकारी आपके निर्देश के दायरे में एक विधि को पारित करने के लिए है ताकि इसे आपके निर्देश में बुलाया जा सके। विधि निर्देशक के मूल दायरे से पूर्व-बाध्य है, और तर्कों का समर्थन करती है। उदाहरण के लिए यदि विधि मूल दायरे में हैलो (नाम) है, तो अपने निर्देश के अंदर से विधि को निष्पादित करने के लिए, आपको $ scope.hello ({name: 'world'} कॉल करना होगा)

मुझे लगता है कि छोटे अंतर से गुंजाइश बाइंडिंग का जिक्र करते हुए इन मतभेदों को याद रखना आसान है:

  • @ विशेषता स्ट्रिंग बाध्यकारी
  • = दो-तरफा मॉडल बाध्यकारी
  • & कॉलबैक विधि बाध्यकारी

प्रतीक यह भी स्पष्ट करते हैं कि आपके निर्देश के कार्यान्वयन के अंदर स्कोप वेरिएबल क्या दर्शाता है:

  • @ स्ट्रिंग
  • = मॉडल
  • & विधि

उपयोगिता के क्रम में (मेरे लिए वैसे भी):

  1. =
  2. @
  3. और

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

@ मतलब है कि वेरिएबल को निर्देश में कॉपी किया जाएगा (क्लोन)।

जहां तक ​​मुझे पता है, <pane bi-title="{{title}}" title="{{title}}">{{text}}</pane> भी काम करना चाहिए। bi-title माता bi-title पिता स्कोप वैरिएबल मान प्राप्त करेगा, जिसे निर्देश में बदला जा सकता है।

यदि आपको मूल दायरे में कई चर बदलने की आवश्यकता है, तो आप निर्देश के भीतर से मूल दायरे पर एक फ़ंक्शन निष्पादित कर सकते हैं (या किसी सेवा के माध्यम से डेटा पास कर सकते हैं)।


@ और = अन्य उत्तरों देखें।

एक गोचा के बारे में &
टी एल; डॉ;
& माता-पिता से अभिव्यक्ति प्राप्त होती है (न केवल अन्य उत्तरों में उदाहरणों की तरह कार्य करती है), और इसे निर्देश में एक फ़ंक्शन के रूप में सेट करती है, जो अभिव्यक्ति को कॉल करती है। और इस फ़ंक्शन में वेरिएबल के साथ ऑब्जेक्ट पास करके अभिव्यक्ति के किसी भी चर (यहां तक ​​कि फ़ंक्शन नाम) को प्रतिस्थापित करने की क्षमता है।

व्याख्या की
& एक अभिव्यक्ति संदर्भ है, जिसका अर्थ है कि यदि आप <myDirective expr="x==y"></myDirective>
निर्देश में यह expr एक कार्य होगा, जो अभिव्यक्ति को कॉल करता है, जैसे:
function expr(){return x == y}
इसलिए निर्देश के एचटीएमएल <button ng-click="expr()"></button> अभिव्यक्ति को कॉल करेगा। निर्देश के जेएस में सिर्फ $scope.expr() अभिव्यक्ति को भी कॉल करेगा।
अभिव्यक्ति को माता-पिता के $ scope.x और $ scope.y के साथ बुलाया जाएगा।
आपके पास पैरामीटर को ओवरराइड करने की क्षमता है!
यदि आप उन्हें कॉल करके सेट करते हैं, उदाहरण के लिए <button ng-click="expr({x:5})"></button>
तो अभिव्यक्ति को आपके पैरामीटर x और पैरेंट के पैरामीटर y साथ बुलाया जाएगा।
आप दोनों को ओवरराइड कर सकते हैं।
अब आप जानते हैं, क्यों <button ng-click="functionFromParent({x:5})"></button> काम करता है।
क्योंकि यह केवल माता-पिता की अभिव्यक्ति को कॉल करता है (उदाहरण के लिए <myDirective functionFromParent="function1(x)"></myDirective> ) और इस मान में आपके निर्दिष्ट पैरामीटर के साथ संभावित मानों को प्रतिस्थापित करता है।
यह हो सकता था:
<myDirective functionFromParent="function1(x) + 5"></myDirective>
या
<myDirective functionFromParent="function1(x) + z"></myDirective>
बाल कॉल के साथ:
<button ng-click="functionFromParent({x:5, z: 4})"></button>
या समारोह प्रतिस्थापन के साथ भी:
<button ng-click="functionFromParent({function1: myfn, x:5, z: 4})"></button>

यह सिर्फ एक अभिव्यक्ति है, इससे कोई फर्क नहीं पड़ता कि यह एक समारोह है, या कई कार्यों, या सिर्फ तुलना। और आप इस अभिव्यक्ति के किसी भी चर को प्रतिस्थापित कर सकते हैं।

उदाहरण:
निर्देश टेम्पलेट बनाम कोड कहा जाता है:
माता-पिता ने $ scope.x, $ scope.y परिभाषित किया है:
अभिभावक टेम्पलेट: <myDirective expr="x==y"></myDirective>
<button ng-click="expr()"></button> $scope.x==$scope.y कॉल $scope.x==$scope.y
<button ng-click="expr({x: 5})"></button> कॉल 5 == $scope.y
<button ng-click="expr({x:5, y:6})"></button> कॉल 5 == 6

अभिभावक ने $ scope.function1, $ scope.x, $ scope.y परिभाषित किया है:
अभिभावक टेम्पलेट: <myDirective expr="function1(x) + y"></myDirective>

<button ng-click="expr()"></button> $scope.function1($scope.x) + $scope.y
<button ng-click="expr({x: 5})"></button> $scope.function1(5) + $scope.y
<button ng-click="expr({x:5, y:6})"></button> $scope.function1(5) + 6 कॉल करता है
निर्देश के रूप में $ scope.myFn निर्देश है:
<button ng-click="expr({function1: myFn, x:5, y:6})"></button> $scope.myFn(5) + 6 कॉल करता है


= रास्ता 2-तरफा बाध्यकारी है , जो आपको अपने निर्देश के अंदर लाइव परिवर्तन करने देता है। जब कोई उस निर्देश को निर्देश के बाहर बदलता है, तो आपके पास उस निर्देश को आपके निर्देश के अंदर बदल दिया जाएगा, लेकिन @ रास्ता दो तरीकों से बाध्यकारी नहीं है । यह पाठ की तरह काम करता है। आप एक बार बांधते हैं, और आपके पास केवल इसका मूल्य होगा।

इसे और अधिक स्पष्ट रूप से प्राप्त करने के लिए, आप इस महान लेख का उपयोग कर सकते हैं:

AngularJS निर्देश स्कोप '@' और '='






isolated-scope