angularjs-directive - Angularjs के बारे में उलझन में स्कॉप्स और बाइंडिंग अलग और अलग





angularjs-scope (4)


अच्छा पूछा, बीटीडब्ल्यू! आशा है कि मेरा जवाब वाक्प्रचार के रूप में है ..

इसका जवाब यह है कि कैसे निर्वहन तत्वों को अपना दायरा मिलता है।

संक्षेप में, आपके पास दो स्कोप हैं:

  1. नियंत्रक का दायरा, जिसमें $scope.data.title । (आपके input तत्व द्वारा लागू रूप से जोड़ा गया)
  2. निर्देश का दायरा, जिसमें $scope.title

जब आप नियंत्रक के $scope.data.title , तो निर्देशक का $scope.title भी बदल जाता है।

आपके पास HTML, स्थानांतरित और टेम्पलेट के दो अनुभाग भी हैं। क्या हो रहा है कि स्थानांतरित एचटीएमएल नियंत्रक के दायरे में है, और टेम्पलेट एचटीएमएल निर्देशक के दायरे में है। इसलिए स्थानांतरित एचटीएमएल title बारे में कुछ भी नहीं जानता है, और टेम्पलेट स्कोप data.title . data.title बारे में कुछ भी नहीं जानता है

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

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

मैंने नाम को थोड़ा और स्पष्ट करने के लिए थोड़ा सा कोड बदल दिया है (समान कार्यक्षमता, हालांकि)

http://jsfiddle.net/yWWVs/2/

मैं सीमित दायरे वाले निर्देशों के संबंध में मॉडल और उनके बाइंडिंग के दायरे को समझने के लिए संघर्ष कर रहा हूं।

मुझे लगता है कि निर्देश पर दायरे को सीमित करना मतलब है कि नियंत्रक। $ स्कोप और directive.scope अब एक ही बात नहीं है। हालांकि, मैं इस बारे में उलझन में हूं कि मॉडलों को निर्देश टेम्पलेट के भीतर या एचटीएमएल में डेटा बाध्यकारी को कैसे प्रभावित करता है। मुझे लगता है कि मुझे कुछ मौलिक याद आ रही है और आगे बढ़ने के लिए मुझे इसे समझने की जरूरत है।

निम्नलिखित कोड लें (यहां बेवकूफ: http://jsfiddle.net/2ams6/ )

जावास्क्रिप्ट

var app = angular.module('app',[]);
app.controller('Ctrl',function($scope){
});
app.directive('testel', function(){
    return {
        restrict: 'E',
        scope: {
            title: '@'
        },
        transclude: true,
        template:   '<div ng-transclude>'+
                    '<h3>Template title: {{title}}</h3>' +
                    '<h3>Template data.title:{{data.title}}</h3>' +
                    '</div>'
    }    
}); 

एचटीएमएल

<div ng-app='app'>
    <div ng-controller="Ctrl">
        <input ng-model="data.title">
        <testel title="{{data.title}}">
            <h3>Transclude title:{{title}}</span></h3>
            <h3>Transclude data.title:{{data.title}}</h3>
        </testel>
    </div>
</div>

मॉडल केवल टेम्पलेट के भीतर {{title}} अपडेट करता है, और {{data.title}} को {{data.title}} करता है। टेम्पलेट में {{title}} और न ही {{data.title}} क्यों {{title}} ?

इस तरह के स्थानांतरण के भीतर इनपुट को स्थानांतरित करना (यहां बेवकूफ: http://jsfiddle.net/eV8q8/1/ ):

<div ng-controller="Ctrl">
    <testel title="{{data.title}}">
        <input ng-model="data.title">
         <h3>Transclude title: <span style="color:red">{{title}}</span></h3>

         <h3>Transclude data.title: <span style="color:red">{{data.title}}</span></h3>

    </testel>
</div>

अब केवल {{data:title}} को स्थानांतरित करने का अर्थ अपडेट हो जाता है। क्यों टेम्पलेट {{title}} या {{data.title}} , और न ही {{title}} स्थानांतरित {{title}} ?

और अंत में, इनपुट को टेम्पलेट के भीतर ले जाना, जैसे कि (यहां बेवकूफ: http://jsfiddle.net/4ngmf/2/ ):

template: '<div ng-transclude>' +
            '<input ng-model="data.title" />' +
            '<h3>Template title: {{title}}</h3>' +
            '<h3>Template data.title: {{data.title}}</h3>' +
            '</div>'

अब इसका मतलब है कि केवल टेम्पलेट {{data.title}} अपडेट हो जाता है। फिर, अन्य 3 बाइंडिंग क्यों नहीं?

मुझे उम्मीद है कि चेहरे में मुझे कुछ स्पष्ट दिख रहा है और मुझे यह याद आ रही है। यदि आप मुझे यह प्राप्त करने के लिए प्राप्त करते हैं, तो मैं आपको एक बियर खरीदूंगा, या आपको कुछ अंक, या कुछ अन्य चीज़ दे दूंगा। बहुत धन्यवाद।




आपके fiddles तीन scopes बनाते हैं:

  1. ng-controller वजह से नियंत्रक Ctrl जुड़े एक दायरे
  2. पारगमन की वजह से एक निर्देश पारदर्शी दायरा transclude: true
  3. दायरे के कारण, एक दायरा अलग करने का निर्देश scope: { ... }

Fiddle1 में, हम टेक्स्ट बॉक्स में कुछ भी टाइप करने से पहले हमारे पास निम्न है:

स्कोप 003 नियंत्रक से जुड़ा गुंजाइश है। चूंकि हमने अभी तक टेक्स्टबॉक्स में टाइप नहीं किया है, इसलिए कोई data प्रॉपर्टी नहीं है। अलग-अलग दायरे में 004, हम देखते हैं कि एक title संपत्ति बनाई गई थी, लेकिन यह खाली है। यह खाली है क्योंकि मूल दायरे में अभी तक data.title संपत्ति नहीं है।

टेक्स्टबॉक्स में my title टाइप करने के बाद, अब हमारे पास है:

कंट्रोलर स्कोप 003 में अब एक नई data ऑब्जेक्ट प्रॉपर्टी है (यही कारण है कि यह रंगीन पीला है), जिसमें title जो अब my title सेट है। चूंकि स्कोप प्रॉपर्टी title data.title के इंटरपोलेटेड वैल्यू के लिए एक data.title , इसलिए यह my title का मान भी प्राप्त करता है (मान रंगीन पीला है क्योंकि यह बदल गया है)।

स्थानांतरित स्कॉप प्रोटोटाइप रूप से नियंत्रक दायरे से प्राप्त होता है, इसलिए स्थानांतरित एचटीएमएल के अंदर, कोणीय प्रोटोटाइप श्रृंखला का पालन कर सकता है और मूल दायरे में $scope.title है (लेकिन $scope.title वहां मौजूद नहीं है)।

अलग-अलग दायरे में केवल अपनी संपत्तियों तक पहुंच है, इसलिए केवल संपत्ति का title

Fiddle2 में, टाइप करने से पहले हमारे पास fiddle1 जैसा ही चित्र है।

my title टाइप करने के बाद:

ध्यान दें कि नई data.title संपत्ति दिखाया गया है - स्थानांतरित दायरे पर। अलग-अलग दायरे अभी भी नियंत्रक दायरे पर data.title तलाश में है, लेकिन यह इस समय नहीं है, इसलिए इसका title संपत्ति मूल्य खाली रहता है।

Fiddle3 में, टाइप करने से पहले हमारे पास fiddle1 जैसा ही चित्र है।

my title टाइप करने के बाद:

ध्यान दें कि नई data.title संपत्ति - अलग-अलग दायरे पर दिखाई दे रही है। अन्य स्कॉप्स में से कोई भी अलग-अलग दायरे तक पहुंच नहीं है, इसलिए my title स्ट्रिंग कहीं और नहीं दिखाई देगा।

कोणीय v1.2 के लिए अद्यतन करें:

परिवर्तन eed299a साथ कोणीय अब स्थानांतरित करने से पहले स्थानांतरण बिंदु को साफ़ करता है, इसलिए Template title: ... और Template data.title: ... भागों को तब तक प्रदर्शित नहीं किया जाएगा जब तक कि आप टेम्पलेट को संशोधित न करें जैसे कि ng-transclude स्वयं ही है, जैसे जैसा:

'<h3>Template title: <span style="color:red">{{title}}</span></h3>' +
'<h3>Template data.title: <span style="color:red">{{data.title}}</span></h3>' +
'<div ng-transclude></div>'

कोणीय v1.3 के लिए नीचे दिए गए अद्यतन में, यह टेम्पलेट परिवर्तन किया गया था।

कोणीय v1.3 + के लिए अद्यतन करें:

कोणीय v1.3 के बाद से, स्थानांतरित गुंजाइश अब नियंत्रक के दायरे के बच्चे के बजाय निर्देश के अलग-अलग दायरे का एक बच्चा है। तो fiddle1 में, हम कुछ भी टाइप करने से पहले:

इस अद्यतन में चित्र Peri$scope टूल के साथ खींचे गए हैं, इसलिए चित्र थोड़ा अलग हैं। @ इंगित करता है कि हमारे पास एक अलग स्कोप प्रॉपर्टी है जो @ सिंटैक्स का उपयोग करती है, और गुलाबी पृष्ठभूमि का अर्थ है कि टूल मैपिंग के लिए पूर्वजों का संदर्भ नहीं ढूंढ पाया (जो सच है, क्योंकि हमने अभी तक टेक्स्टबॉक्स में कुछ भी टाइप नहीं किया है )।

टेक्स्टबॉक्स में my title टाइप करने के बाद, अब हमारे पास है:

@ बाध्यकारी का उपयोग करने वाले गुणों को अलग करें हमेशा @ प्रतीक के बाद अलग-अलग दायरे में इंटरपोलेटेड स्ट्रिंग परिणाम दिखाएंगे। पेरी $ स्कोप इस पूर्व स्ट्रिंग मान को पूर्वजों के दायरे में भी ढूंढने में सक्षम था, इसलिए यह उस संपत्ति का संदर्भ भी दिखाता है।

पहेली 2 में, टाइप करने से पहले हमारे पास fiddle1 जैसा ही चित्र है।

my title टाइप करने के बाद:

ध्यान दें कि नई data.title संपत्ति दिखाया गया है - स्थानांतरित दायरे पर। अलग-अलग दायरे अभी भी नियंत्रक दायरे पर data.title तलाश में है, लेकिन यह इस समय नहीं है, इसलिए इसका title संपत्ति मूल्य खाली रहता है।

Fiddle3 में, टाइप करने से पहले हमारे पास fiddle1 जैसा ही चित्र है।

my title टाइप करने के बाद:

ध्यान दें कि नई data.title संपत्ति - अलग-अलग दायरे पर दिखाई दे रही है। भले ही स्थानांतरित दायरे के पास $parent संबंधों के माध्यम से अलग-अलग दायरे तक पहुंच हो, फिर भी यह title या data.title title लिए नहीं data.title - यह केवल नियंत्रक दायरे में दिखाई देगा (यानी, यह प्रोटोटाइप विरासत का पालन करेगा) और नियंत्रक दायरे में इन गुणों को परिभाषित नहीं किया गया है।




मार्क के शानदार स्कीमेटिक्स समेत प्रस्तुत किए गए सभी उत्तरों को पढ़ने के बाद, यह मेरी समझ है और यह मेरे प्रश्न के प्रति विरासत है। मैं इस आरेख को कहां गिरता हूं, इस पर टिप्पणियों की सराहना करता हूं, ताकि मैं उचित रूप से अपडेट कर सकूं। मुझे आशा है कि यह मार्क ने जो प्रस्तुत किया है, उसके लिए यह एक अलग दृश्य प्रदान करता है:




स्पष्ट रूप से Scope की कोई आवधिक जांच नहीं है कि इससे जुड़े ऑब्जेक्ट्स में कोई बदलाव है या नहीं। गुंजाइश से जुड़ी सभी वस्तुओं को देखा नहीं जाता है। स्कोप प्रोटोटाइपिक रूप से $$ वॉचर्स रखता है। जब $digest को बुलाया जाता है तो Scope केवल $$watchers वॉचर्स के माध्यम से पुनरावृत्त होता है।

कोणीय इनमें से प्रत्येक के लिए $$ निरीक्षक को एक वॉचर जोड़ता है

  1. {{अभिव्यक्ति}} - आपके टेम्पलेट्स (और कहीं और जहां एक अभिव्यक्ति है) में या जब हम एनजी-मॉडल को परिभाषित करते हैं।
  2. $ स्कोप। $ घड़ी ('अभिव्यक्ति / फ़ंक्शन') - आपकी जावास्क्रिप्ट में हम केवल कोणीय देखने के लिए एक स्कोप ऑब्जेक्ट संलग्न कर सकते हैं।

$ घड़ी फ़ंक्शन तीन पैरामीटर में लेता है:

  1. पहला एक वॉचर फ़ंक्शन है जो ऑब्जेक्ट देता है या हम केवल एक अभिव्यक्ति जोड़ सकते हैं।

  2. दूसरा एक श्रोता समारोह है जिसे ऑब्जेक्ट में कोई परिवर्तन होने पर बुलाया जाएगा। डीओएम परिवर्तन जैसी सभी चीजें इस समारोह में लागू की जाएंगी।

  3. तीसरा एक वैकल्पिक पैरामीटर है जो बुलियन में होता है। यदि यह सच है, कोणीय गहरी वस्तु को देखता है और यदि इसका झूठा कोणीय वस्तु पर एक संदर्भ देखता है। $ घड़ी का असर कार्यान्वयन इस तरह दिखता है

Scope.prototype.$watch = function(watchFn, listenerFn) {
   var watcher = {
       watchFn: watchFn,
       listenerFn: listenerFn || function() { },
       last: initWatchVal  // initWatchVal is typically undefined
   };
   this.$$watchers.push(watcher); // pushing the Watcher Object to Watchers  
};

अंगुलर में डाइजेस्ट साइकिल नामक एक दिलचस्प बात है। $ पाचन चक्र के कॉल के परिणामस्वरूप $ पाचन चक्र शुरू होता है। $ Digest ()। मान लें कि आप एनजी-क्लिक निर्देश के माध्यम से एक हैंडलर फ़ंक्शन में $ स्कोप मॉडल बदलते हैं। उस स्थिति में AngularJS स्वचालित रूप से $ digest () को कॉल करके $ पाचन चक्र को ट्रिगर करता है। एनजी-क्लिक के अलावा, कई अन्य अंतर्निहित निर्देश / सेवाएं हैं जो आपको मॉडल बदलने देती हैं (जैसे एनजी-मॉडल, $ टाइमआउट, आदि) और स्वचालित रूप से एक $ पाचन चक्र ट्रिगर। $ पाचन का मोटा कार्यान्वयन इस तरह दिखता है।

Scope.prototype.$digest = function() {
      var dirty;
      do {
          dirty = this.$$digestOnce();
      } while (dirty);
}
Scope.prototype.$$digestOnce = function() {
   var self = this;
   var newValue, oldValue, dirty;
   _.forEach(this.$$watchers, function(watcher) {
          newValue = watcher.watchFn(self);
          oldValue = watcher.last;   // It just remembers the last value for dirty checking
          if (newValue !== oldValue) { //Dirty checking of References 
   // For Deep checking the object , code of Value     
   // based checking of Object should be implemented here
             watcher.last = newValue;
             watcher.listenerFn(newValue,
                  (oldValue === initWatchVal ? newValue : oldValue),
                   self);
          dirty = true;
          }
     });
   return dirty;
 };

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

Scope.prototype.$apply = function(expr) {
       try {
         return this.$eval(expr); //Evaluating code in the context of Scope
       } finally {
         this.$digest();
       }
};




angularjs angularjs-directive angularjs-scope