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




angularjs-directive angularjs-scope (12)

मैंने विषय पर 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 विशेषता द्वारा परिभाषित अभिव्यक्ति (या फ़ंक्शन) को कॉल करने की अनुमति देता है - और आप अभिव्यक्ति या फ़ंक्शन के लिए तर्क के रूप में डेटा भी पास कर सकते हैं। इसलिए, यदि आपको माता-पिता के साथ डेटा साझा करने की आवश्यकता नहीं है - तो आप केवल मूल दायरे में परिभाषित फ़ंक्शन को कॉल करना चाहते हैं - आप & वाक्यविन्यास का उपयोग कर सकते हैं।

यह भी देखें


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

  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 है जो इसे अच्छी तरह से वर्णन करता है।


यहां तक ​​कि जब दायरा स्थानीय है, जैसा कि आपके उदाहरण में है, आप संपत्ति $parent माध्यम से अभिभावक के दायरे तक पहुंच सकते हैं। नीचे दिए गए कोड में मान लें, वह title मूल दायरे पर परिभाषित किया गया है। फिर आप शीर्षक को $parent.title रूप में एक्सेस कर सकते हैं:

link : function(scope) { console.log(scope.$parent.title) },
template : "the parent has the title {{$parent.title}}"

हालांकि ज्यादातर मामलों में वही प्रभाव विशेषताओं का उपयोग करके बेहतर होता है।

एक उदाहरण जहां मैंने "&" नोटेशन पाया, जिसका प्रयोग "अभिव्यक्ति के माध्यम से अलग-अलग दायरे से डेटा पास करने के लिए और अभिभावक के दायरे में" करने के लिए किया जाता है, उपयोगी (और दो-तरफा डाटाबेसिंग का उपयोग नहीं किया जा सकता) निर्देश में था एक ng-repeat के अंदर एक विशेष डेटास्ट्रक्चर प्रस्तुत करने के लिए।

<render data = "record" deleteFunction = "dataList.splice($index,1)" ng-repeat = "record in dataList" > </render>

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

scope : { data = "=", deleteFunction = "&"},
template : "... <button ng-click = "deleteFunction()"></button>"

2-तरफा डाटाबेसिंग यानी data = "=" उपयोग नहीं किया जा सकता है क्योंकि डिलीट फ़ंक्शन प्रत्येक $digest चक्र पर चलाया जाएगा, जो अच्छा नहीं है, क्योंकि रिकॉर्ड तुरंत हटा दिया जाता है और कभी भी प्रस्तुत नहीं किया जाता है।


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

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

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


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

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

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

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

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

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

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

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

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


मैंने एक छोटी HTML फ़ाइल बनाई जिसमें कोणीय कोड उनके बीच अंतर प्रदर्शित करता है:

https://gist.github.com/RobertAKARobin/a02426c375596f0bef89

<!DOCTYPE html>
<html>
  <head>
    <title>Angular</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
  </head>
  <body ng-app="myApp">
    <div ng-controller="myCtrl as VM">
      <a my-dir
        attr1="VM.sayHi('Juan')"
        attr2="VM.sayHi('Juan')"
        attr3="VM.sayHi('Juan')"></a>
    </div>
    <script>
    angular.module("myApp", [])
    .controller("myCtrl", [function(){
      var vm = this;
      vm.sayHi = function(name){
        return ("Hey there, " + name);
      }
    }])
    .directive("myDir", [function(){
      var directive = {
        scope: { attr1: "=", attr2: "@", attr3: "&" },
        link: function(scope){
          console.log(scope.attr1);   // logs "Hey there, Juan"
          console.log(scope.attr2);   // logs "VM.sayHi('Juan')"
          console.log(scope.attr3);   // logs "function (a){return h(c,a)}"
          console.log(scope.attr3()); // logs "Hey there, Juan"
        }
      }
      return directive;
    }]);
    </script>
  </body>
</html>

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

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

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

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


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

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

scope:{
    name:'&'
},

scope:{
    name:'='
},

scope:{
    name:'@'
},

scope:{

},

scope:true,

https://jsfiddle.net/rishulmatta/v7xf2ujm


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

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

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

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

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

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

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

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

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

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

  1. =
  2. @
  3. और

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


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

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

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

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

संपादित करें

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

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

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

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


@ स्ट्रिंग के रूप में मिलता है

  • यह किसी भी बाध्यकारी नहीं बनाता है। आप बस एक शब्द के रूप में पारित शब्द प्राप्त कर रहे हैं

= 2 रास्ता बाध्यकारी

  • नियंत्रक से किए गए परिवर्तन निर्देश द्वारा आयोजित संदर्भ में प्रतिबिंबित होंगे, और इसके विपरीत

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

  • इस गेटर फ़ंक्शन को कॉल करने के बाद, परिणामस्वरूप ऑब्जेक्ट निम्नानुसार व्यवहार करता है:
    • यदि कोई फ़ंक्शन पारित किया गया था: तो फ़ंक्शन को कॉल किए जाने पर पैरेंट (नियंत्रक) बंद करने में निष्पादित किया जाता है
    • यदि कोई गैर-फ़ंक्शन पारित किया गया था: बस उस ऑब्जेक्ट की स्थानीय प्रति प्राप्त करें जिसमें कोई बाइंडिंग नहीं है


यह बेवकूफ दिखाना चाहिए कि वे कैसे काम करते हैं । स्कोप फ़ंक्शंस पर विशेष ध्यान दें get... नाम में उम्मीद है कि मैं समझता हूं कि मेरे बारे में क्या मतलब है &







isolated-scope