javascript - AngularJS में डेटा बाध्यकारी कार्य कैसे करता है?




data-binding (12)

AngularJS ढांचे में डेटा बाध्यकारी काम कैसे करता है?

मुझे उनकी साइट पर तकनीकी विवरण नहीं मिला है। जब डेटा को मॉडल से देखने के लिए प्रचारित किया जाता है तो यह कम या ज्यादा स्पष्ट होता है। लेकिन AngularJS कैसे सेटर्स और गेटर्स के बिना मॉडल गुणों में परिवर्तन करता है?

मैंने पाया कि जावास्क्रिप्ट वॉचर्स हैं जो यह काम कर सकते हैं। लेकिन वे Internet Explorer 6 और Internet Explorer 7 में समर्थित नहीं हैं। तो AngularJS कैसे जानता है कि मैंने उदाहरण के लिए निम्नलिखित बदल दिया और इस बदलाव को एक दृश्य पर प्रतिबिंबित किया?

myobject.myproperty="new value";

Answers

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

जैसा कि मिस्को ने कहा, लगभग 2000 बाइंडिंग्स है जहां आप समस्याओं को देखना शुरू करते हैं, लेकिन आपके पास किसी पृष्ठ पर 2000 से अधिक जानकारी की जानकारी नहीं होनी चाहिए। यह सच हो सकता है, लेकिन उपयोगकर्ता के लिए प्रत्येक डेटा-बाध्यकारी दिखाई नहीं दे रहा है। एक बार जब आप किसी भी प्रकार के विजेट या डेटा ग्रिड को दो-तरफा बाध्यकारी के साथ बनाना शुरू कर देते हैं तो आप खराब ux के बिना 2000 बाइंडिंग आसानी से हिट कर सकते हैं

उदाहरण के लिए, एक combobox पर विचार करें जहां आप उपलब्ध विकल्पों को फ़िल्टर करने के लिए टेक्स्ट टाइप कर सकते हैं। इस तरह के नियंत्रण में ~ 150 आइटम हो सकते हैं और अभी भी अत्यधिक उपयोग योग्य हो सकते हैं। यदि इसमें कुछ अतिरिक्त सुविधा है (उदाहरण के लिए वर्तमान में चयनित विकल्प पर एक विशिष्ट श्रेणी) तो आप प्रति विकल्प 3-5 बाइंडिंग प्राप्त करना शुरू कर देते हैं। इन तीनों विजेटों को एक पृष्ठ पर रखें (उदाहरण के लिए एक देश का चयन करने के लिए, दूसरा देश में एक शहर का चयन करने के लिए, और तीसरा होटल चुनने के लिए) और आप कहीं 1000 और 2000 बाइंडिंग के बीच कहीं हैं।

या कॉर्पोरेट वेब एप्लिकेशन में डेटा-ग्रिड पर विचार करें। प्रति पृष्ठ 50 पंक्तियां अनुचित नहीं हैं, जिनमें से प्रत्येक में 10-20 कॉलम हो सकते हैं। यदि आप इसे एनजी-दोहराने के साथ बनाते हैं, और / या कुछ बाइंडिंग का उपयोग करने वाली कुछ कोशिकाओं में जानकारी है, तो आप अकेले इस ग्रिड के साथ 2000 बाइंडिंग तक पहुंच सकते हैं।

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

मुझे इसे संभालने के अन्य तरीकों पर सुझाव सुनना अच्छा लगेगा, लेकिन फिर मुझे अपना खुद का प्रश्न लिखना चाहिए। मैं इसे एक टिप्पणी में रखना चाहता था, लेकिन यह उस के लिए रास्ता बहुत लंबा हो गया ...

टी एल; डॉ
डेटा बाध्यकारी जटिल पृष्ठों पर प्रदर्शन मुद्दों का कारण बन सकता है।


AngularJS मान को याद करता है और इसे पिछले मान से तुलना करता है। यह मूल गंदा जांच है। यदि मूल्य में कोई बदलाव है, तो यह परिवर्तन घटना को सक्रिय करता है।

$apply() विधि, जिसे आप गैर-कोणीय जेएस दुनिया से एंगुलरजेएस दुनिया में परिवर्तित करते समय कॉल करते हैं, $digest() । एक पाचन सिर्फ सादा पुरानी गंदा जांच है। यह सभी ब्राउज़रों पर काम करता है और पूरी तरह अनुमानित है।

गंदे-जांच (एंगुलरजेएस) बनाम श्रोताओं को बदलने के लिए ( KnockoutJS और Backbone.js ): जबकि गंदा जांच सरल लग सकती है, और यहां तक ​​कि अक्षम (मैं बाद में इसे संबोधित करूंगा), यह पता चला है कि यह हर समय अर्थपूर्ण रूप से सही है, जबकि श्रोताओं के पास बहुत सारे अजीब कोने के मामले हैं और इसे निर्भरता ट्रैकिंग जैसी चीजों की आवश्यकता है ताकि इसे अधिक अर्थपूर्ण रूप से सही बनाया जा सके। KnockoutJS निर्भरता ट्रैकिंग एक समस्या के लिए एक चालाक सुविधा है जो AngularJS नहीं है।

परिवर्तन श्रोताओं के साथ मुद्दे:

  • वाक्यविन्यास अत्याचारी है, क्योंकि ब्राउज़र इसे मूल रूप से समर्थन नहीं करते हैं। हां, प्रॉक्सी हैं, लेकिन वे सभी मामलों में अर्थात् सही नहीं हैं, और निश्चित रूप से पुराने ब्राउज़र पर कोई प्रॉक्सी नहीं है। निचली पंक्ति यह है कि गंदा जांच आपको POJO करने की अनुमति देती है, जबकि नॉकआउटजेएस और बैकबोन.जेएस आपको अपनी कक्षाओं से प्राप्त करने के लिए मजबूर करते हैं, और एक्सेसर्स के माध्यम से अपने डेटा तक पहुंचते हैं।
  • सहवास बदलें। मान लें कि आपके पास वस्तुओं की एक श्रृंखला है। मान लें कि आप एक सरणी में आइटम जोड़ना चाहते हैं, क्योंकि आप जोड़ने के लिए लूपिंग कर रहे हैं, हर बार जब आप जोड़ते हैं तो आप बदलाव पर घटनाओं को फायर कर रहे हैं, जो यूआई को प्रस्तुत कर रहा है। यह प्रदर्शन के लिए बहुत बुरा है। आप जो चाहते हैं वह अंत में केवल एक बार यूआई अपडेट करना है। परिवर्तन की घटनाएं बहुत अच्छी हैं।
  • श्रोताओं को तुरंत एक सेटर पर आग लगाना, जो एक समस्या है, क्योंकि परिवर्तन श्रोता डेटा को और बदल सकता है, जो अधिक परिवर्तन घटनाओं को सक्रिय करता है। यह आपके स्टैक पर खराब है क्योंकि आपके पास कई बदलाव घटनाएं हो सकती हैं। मान लें कि आपके पास दो एरे हैं जिन्हें किसी भी कारण से सिंक में रखा जाना चाहिए। आप केवल एक या दूसरे में जोड़ सकते हैं, लेकिन हर बार जब आप एक बदलाव घटना को आग लगाते हैं, जो अब दुनिया का एक असंगत दृश्य है। थ्रेड लॉकिंग के लिए यह एक बहुत ही समान समस्या है, जो जावास्क्रिप्ट से बचाता है क्योंकि प्रत्येक कॉलबैक विशेष रूप से और पूरा होने के लिए निष्पादित होता है। ईवेंट बदलें इसे तोड़ दें क्योंकि सेटर के पास दूरगामी परिणाम हो सकते हैं जो इरादे से नहीं हैं और स्पष्ट नहीं हैं, जो थ्रेड समस्या को फिर से बनाता है। यह पता चला है कि आप क्या करना चाहते हैं श्रोता निष्पादन में देरी करना, और गारंटी है कि केवल एक श्रोता एक समय में चलता है, इसलिए कोई भी कोड डेटा बदलने के लिए स्वतंत्र है, और यह जानता है कि ऐसा कोई अन्य कोड नहीं चल रहा है ।

प्रदर्शन के बारे में क्या?

तो ऐसा लगता है कि हम धीमे हैं, क्योंकि गंदा जांच अक्षम है। यह वह जगह है जहां हमें केवल सैद्धांतिक तर्कों की बजाय वास्तविक संख्याओं को देखने की आवश्यकता है, लेकिन पहले कुछ बाधाओं को परिभाषित करते हैं।

मनुष्य हैं:

  • धीमा - 50 एमएस से भी तेज कुछ भी इंसानों के लिए अतिसंवेदनशील है और इस प्रकार इसे "तत्काल" माना जा सकता है।

  • सीमित - आप वास्तव में एक पृष्ठ पर किसी मानव को जानकारी के 2000 से अधिक टुकड़े नहीं दिखा सकते हैं। उससे भी ज्यादा कुछ वास्तव में खराब यूआई है, और मनुष्य वैसे भी इसे संसाधित नहीं कर सकते हैं।

तो वास्तविक सवाल यह है: 50 एमएस में ब्राउज़र पर आप कितनी तुलना कर सकते हैं? जवाब देने के लिए यह एक कठिन सवाल है क्योंकि कई कारक खेलते हैं, लेकिन यहां एक टेस्ट केस है: http://jsperf.com/angularjs-digest/6 जो 10,000 दर्शक बनाता है। एक आधुनिक ब्राउज़र पर यह केवल 6 एमएस से कम लेता है। Internet Explorer 8 इसमें लगभग 40 एमएस लगते हैं। जैसा कि आप देख सकते हैं, यह इन दिनों धीमे ब्राउज़र पर भी कोई मुद्दा नहीं है। एक चेतावनी है: तुलना को समय सीमा में फिट करने के लिए सरल होना आवश्यक है ... दुर्भाग्य से एंगुलरजेएस में धीमी तुलना जोड़ने के लिए यह बहुत आसान है, इसलिए धीमे अनुप्रयोगों को बनाना आसान है जब आप नहीं जानते कि आप क्या जानते हैं कर रहे हैं। लेकिन हमें एक उपकरण मॉड्यूल प्रदान करके एक उत्तर देने की उम्मीद है, जो आपको दिखाएगा कि धीमी तुलना कौन सा है।

यह पता चला है कि वीडियो गेम और जीपीयू गंदे-जांच दृष्टिकोण का उपयोग करते हैं, खासकर क्योंकि यह सुसंगत है। जब तक वे मॉनिटर रीफ्रेश दर (आमतौर पर 50-60 हर्ट्ज, या हर 16.6-20 एमएस) पर पहुंच जाते हैं, तब तक कोई भी प्रदर्शन एक अपशिष्ट है, इसलिए आप एफपीएस उच्च होने की तुलना में अधिक सामान खींचने से बेहतर होते हैं।


ऐसा हुआ कि मुझे किसी व्यक्ति के डेटा मॉडल को एक फॉर्म से जोड़ने की ज़रूरत थी, जो मैंने किया था, वह फ़ॉर्म के साथ डेटा का सीधा मैपिंग था।

उदाहरण के लिए यदि मॉडल में कुछ ऐसा था:

$scope.model.people.name

फॉर्म का नियंत्रण इनपुट:

<input type="text" name="namePeople" model="model.people.name">

इस तरह यदि आप ऑब्जेक्ट नियंत्रक के मान को संशोधित करते हैं, तो यह दृश्य में स्वचालित रूप से दिखाई देगा।

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


स्पष्ट रूप से 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();
       }
};

गंदे द्वारा $scope ऑब्जेक्ट की जांच कर रहा है

कोणीय $scope ऑब्जेक्ट्स में वॉचर्स की एक साधारण array रखता है। यदि आप किसी भी $scope का निरीक्षण करते हैं तो आप पाएंगे कि इसमें $$watchers नामक एक array

प्रत्येक दर्शक एक object है जिसमें अन्य चीजों के बीच होता है

  1. एक अभिव्यक्ति जो वॉचर निगरानी कर रही है। यह सिर्फ एक attribute नाम हो सकता है, या कुछ और जटिल हो सकता है।
  2. अभिव्यक्ति का अंतिम ज्ञात मूल्य। यह अभिव्यक्ति के वर्तमान गणना मूल्य के खिलाफ जांच की जा सकती है। यदि मूल्य भिन्न होते हैं तो दर्शक फ़ंक्शन को ट्रिगर करेगा और $scope को गंदे के रूप में चिह्नित करेगा।
  3. एक कार्य जो निष्पादित किया जाएगा यदि दर्शक गंदा है।

कैसे निरीक्षक परिभाषित किया जाता है

AngularJS में एक दर्शक को परिभाषित करने के कई अलग-अलग तरीके हैं।

  • आप स्पष्ट attribute से $scope पर एक attribute $watch सकते हैं।

    $scope.$watch('person.username', validateUnique);
    
  • आप अपने टेम्पलेट में एक {{}} इंटरपोलेशन डाल सकते हैं (वर्तमान $scope पर आपके लिए एक वॉचर बनाया जाएगा)।

    <p>username: {{person.username}}</p>
    
  • आप अपने लिए वॉचर को परिभाषित करने के लिए ng-model जैसे निर्देश पूछ सकते हैं।

    <input ng-model="person.username" />
    

$digest चक्र सभी पर्यवेक्षकों को उनके अंतिम मूल्य के खिलाफ जांचता है

जब हम सामान्य चैनलों (एनजी-मॉडल, एनजी-दोहराना, आदि) के माध्यम से एंगुलरजेएस के साथ बातचीत करते हैं तो डायजेस्ट चक्र निर्देश द्वारा ट्रिगर किया जाएगा।

एक पाचन चक्र $scope गहराई और उसके सभी बच्चों की गहराई से पहला ट्रैवर्सल है । प्रत्येक $scope object , हम इसके $$watchers array पर फिर से शुरू होते हैं और सभी अभिव्यक्तियों का मूल्यांकन करते हैं। यदि नया अभिव्यक्ति मान अंतिम ज्ञात मान से अलग है, तो वॉचर के फ़ंक्शन को कॉल किया जाता है। यह फ़ंक्शन DOM का हिस्सा पुन: संकलित कर सकता है, $scope पर एक मान का पुनर्मूल्यांकन कर सकता है, एक AJAX request ट्रिगर कर सकता है, जो कुछ भी आपको करने की ज़रूरत है।

प्रत्येक गुंजाइश को पार किया जाता है और प्रत्येक घड़ी अभिव्यक्ति का मूल्यांकन और अंतिम मूल्य के विरुद्ध चेक किया जाता है।

यदि एक दर्शक ट्रिगर होता है, तो $scope गंदा है

यदि एक वॉचर ट्रिगर होता है, तो ऐप जानता है कि कुछ बदल गया है, और $scope को गंदे के रूप में चिह्नित किया गया है।

वॉचर फ़ंक्शंस अन्य विशेषताओं को $scope या माता-पिता $scope पर बदल सकता है। यदि एक $watcher फ़ंक्शन ट्रिगर किया गया है, तो हम गारंटी नहीं दे सकते कि हमारे अन्य $scope अभी भी साफ हैं, और इसलिए हम पूरे पाचन चक्र को फिर से निष्पादित करते हैं।

ऐसा इसलिए है क्योंकि AngularJS में दो-तरफा बाध्यकारी है, इसलिए डेटा को $scope पेड़ को वापस ले जाया जा सकता है। हम एक उच्च $scope पर एक मूल्य बदल सकते हैं जो पहले से ही पच गया है। शायद हम $rootScope पर एक मूल्य $rootScope

अगर $digest गंदा है, तो हम फिर से पूरे $digest चक्र को निष्पादित करते हैं

जब तक पाचन चक्र साफ नहीं होता है तब तक हम लगातार $digest चक्र के माध्यम से लूप करते हैं (सभी $watch अभिव्यक्तियों के समान चक्र के समान मूल्य होता है), या हम पाचन सीमा तक पहुंचते हैं। डिफ़ॉल्ट रूप से, यह सीमा 10 पर सेट है।

यदि हम पाचन सीमा तक पहुंचते हैं तो AngularJS कंसोल में एक त्रुटि उठाएगा:

10 $digest() iterations reached. Aborting!

पाचन मशीन पर मुश्किल है लेकिन डेवलपर पर आसान है

जैसा कि आप देख सकते हैं, हर बार एंगुलरजेएस ऐप में कुछ बदलाव होता है, एंगुलरजेएस $scope पदानुक्रम में प्रत्येक वॉचर को जवाब देने के तरीके को देखने के लिए जांच करेगा। एक डेवलपर के लिए यह एक बड़े उत्पादकता वरदान है, क्योंकि अब आपको लगभग कोई वायरिंग कोड लिखने की आवश्यकता नहीं है, एंगुलरजेएस सिर्फ यह ध्यान देगा कि कोई मान बदल गया है, और बाकी ऐप को बदलाव के अनुरूप बनाते हैं।

मशीन के परिप्रेक्ष्य से हालांकि यह जंगली रूप से अक्षम है और यदि हम बहुत सारे दर्शक बनाते हैं तो हमारे ऐप को धीमा कर देंगे। आपके ऐप पुराने ब्राउज़रों पर धीमा महसूस करने से पहले मिस्को ने लगभग 4000 वॉचर्स का आंकड़ा उद्धृत किया है।

उदाहरण के लिए यदि आप एक बड़े JSON array पर ng-repeat करते हैं तो यह सीमा तक पहुंच आसान है। आप वॉचर्स बनाये बिना टेम्पलेट को संकलित करने के लिए एक बार बाध्यकारी जैसी सुविधाओं का उपयोग करके इसके खिलाफ कम कर सकते हैं।

बहुत सारे दर्शक बनाने से कैसे बचें

प्रत्येक बार जब आपका उपयोगकर्ता आपके ऐप से इंटरैक्ट करता है, तो आपके ऐप में प्रत्येक वॉचर का मूल्यांकन कम से कम एक बार किया जाएगा। एंगुलरजेएस ऐप को अनुकूलित करने का एक बड़ा हिस्सा आपके $scope पेड़ में वॉचर्स की संख्या को कम कर रहा है। ऐसा करने का एक आसान तरीका एक बार बाध्यकारी है

यदि आपके पास डेटा है जो शायद ही कभी बदल जाएगा, तो आप इसे :: सिंटैक्स का उपयोग करके केवल एक बार बांध सकते हैं, जैसे:

<p>{{::person.username}}</p>

या

<p ng-bind="::person.username"></p>

बाध्यकारी केवल तभी ट्रिगर किया जाएगा जब युक्त टेम्पलेट प्रदान किया जाता है और डेटा $scope में लोड होता $scope

यह विशेष रूप से महत्वपूर्ण है जब आपके पास कई वस्तुओं के साथ ng-repeat

<div ng-repeat="person in people track by username">
  {{::person.username}}
</div>

एक इनपुट फ़ील्ड का उपयोग करके AngularJS के साथ बाध्यकारी डेटा का एक उदाहरण यहां दिया गया है। मैं बाद में समझाऊंगा

HTML कोड

<div ng-app="myApp" ng-controller="myCtrl" class="formInput">
     <input type="text" ng-model="watchInput" Placeholder="type something"/>
     <p>{{watchInput}}</p> 
</div>

AngularJS कोड

myApp = angular.module ("myApp", []);
myApp.controller("myCtrl", ["$scope", function($scope){
  //Your Controller code goes here
}]);

जैसा कि आप ऊपर दिए गए उदाहरण में देख सकते हैं, AngularJS HTML तत्वों पर विशेष रूप से input फ़ील्ड पर क्या होता है सुनने और देखने के लिए ng-model का उपयोग करता है। जब कुछ होता है, तो कुछ करो। हमारे मामले में, मूंछ नोटेशन {{}} का उपयोग करते हुए, ng-model हमारे विचार से जुड़ा हुआ है। जो भी इनपुट फ़ील्ड के अंदर टाइप किया गया है उसे तुरंत स्क्रीन पर प्रदर्शित किया जाता है। और यह AngularJS का उपयोग अपने सबसे सरल रूप में, डेटा बाध्यकारी की सुंदरता है।

उम्मीद है की यह मदद करेगा।

Codepen पर यहां एक कामकाजी उदाहरण देखें


यह मेरी मूल समझ है। यह गलत हो सकता है!

  1. $watch विधि में एक फ़ंक्शन (चीज़ को देखने के लिए वापस लौटकर) पास करके आइटम देखे जाते हैं।
  2. देखे गए आइटमों में परिवर्तन $apply विधि द्वारा लिपटे कोड के ब्लॉक के भीतर किए जाने चाहिए।
  3. $apply के अंत में $digest विधि लागू होती है जो प्रत्येक घड़ियों और चेक के माध्यम से जाती है यह देखने के लिए कि आखिरी बार $digest बाद से वे बदल गए हैं या नहीं।
  4. यदि कोई परिवर्तन पाया जाता है तो सभी परिवर्तन स्थिर होने तक पाचन को फिर से बुलाया जाता है।

सामान्य विकास में, एचटीएमएल में डेटा-बाइंडिंग सिंटैक्स आपके लिए घड़ियों को बनाने के लिए एंगुलरजेएस कंपाइलर को बताता है और नियंत्रक विधियों को पहले ही $apply लिए चलाया जाता है। तो एप्लिकेशन डेवलपर के लिए यह सभी पारदर्शी है।


AngularJs दो तरह के डेटा बाध्यकारी का समर्थन करता है।
मतलब है कि आप डेटा देख सकते हैं -> नियंत्रक और नियंत्रक -> देखें

पूर्व के लिए

1)

// If $scope have some value in Controller. 
$scope.name = "Peter";

// HTML
<div> {{ name }} </div>

ओ / पी

Peter

आप ng-model में डेटा बाध्य कर सकते हैं जैसे: -
2)

<input ng-model="name" />

<div> {{ name }} </div>

यहां उपर्युक्त उदाहरण में जो भी इनपुट उपयोगकर्ता देगा, यह <div> टैग में दिखाई देगा।

अगर एचटीएमएल से नियंत्रक में इनपुट बाध्य करना चाहते हैं: -
3)

<form name="myForm" ng-submit="registration()">
   <label> Name </lbel>
   <input ng-model="name" />
</form>

यहां अगर आप नियंत्रक में इनपुट name का उपयोग करना चाहते हैं, तो,

$scope.name = {};

$scope.registration = function() {
   console.log("You will get the name here ", $scope.name);
};

ng-model हमारे विचार को बांधता है और इसे अभिव्यक्ति में प्रस्तुत करता है {{ }}
ng-model वह डेटा है जो उपयोगकर्ता को दृश्य में दिखाया गया है और जिसके साथ उपयोगकर्ता इंटरैक्ट करता है।
इसलिए AngularJs में डेटा को बांधना आसान है।


Angular.js हमारे द्वारा बनाए गए प्रत्येक मॉडल के लिए एक वॉचर बनाता है। जब भी कोई मॉडल बदल जाता है, तो मॉडल में "एनजी-गंदे" वर्ग लगाया जाता है, इसलिए वॉचर उन सभी मॉडलों का निरीक्षण करेगा जिनमें कक्षा "एनजी-गंदे" है और उनके मूल्य नियंत्रक में और इसके विपरीत अद्यतन करें।


चित्रों के साथ समझाओ:

डेटा-बाइंडिंग को मैपिंग की आवश्यकता होती है

दायरे में संदर्भ बिल्कुल टेम्पलेट में संदर्भ नहीं है। जब आप दो ऑब्जेक्ट्स को डेटा-बाइंड करते हैं, तो आपको तीसरे व्यक्ति की आवश्यकता होती है जो पहले सुनती है और दूसरे को संशोधित करती है।

यहां, जब आप <input> संशोधित करते हैं, तो आप डेटा-रेफ 3 को स्पर्श करते हैं। और क्लासिक डेटा-बाइंड मेकेनिज्म डेटा-रेफ 4 बदल देगा । तो अन्य {{data}} अभिव्यक्ति कैसे बढ़ेगी?

घटनाक्रम $ पाचन ()

कोणीय एक newValue और हर बाध्यकारी के newValue बनाए रखता है। और प्रत्येक कोणीय घटना के बाद, प्रसिद्ध $digest() लूप वॉचलिस्ट को जांचने के लिए जांच करेगा कि कुछ बदल गया है या नहीं। ये कोणीय घटनाएं ng-click , ng-change , $http पूर्ण हो गई हैं ... $digest() तब तक लूप करेगा जब तक कि कोई newValue से अलग newValue

पिछली तस्वीर में, यह ध्यान देगा कि डेटा-रेफ 1 और डेटा-रेफ 2 बदल गया है।

निष्कर्ष

यह अंडे और चिकन की तरह थोड़ा है। आप कभी नहीं जानते कि कौन शुरू होता है, लेकिन उम्मीद है कि यह अपेक्षा के अनुसार अधिकतर समय काम करता है।

दूसरी बात यह है कि आप स्मृति और सीपीयू पर सरल बाध्यकारी के प्रभाव को आसानी से समझ सकते हैं। उम्मीद है कि डेस्कटॉप इसे संभालने के लिए पर्याप्त वसा हैं। मोबाइल फोन उस मजबूत नहीं हैं।


AngularJS तीन शक्तिशाली कार्यों की सहायता से डेटा-बाइंडिंग तंत्र को संभालता है: $watch() , $digest() और $apply() । अधिकांश समय AngularJS $ scope को कॉल करेगा। $ Watch () और $ scope। $ Digest (), लेकिन कुछ मामलों में आपको इन मानों को मैन्युअल रूप से नए मानों के साथ अपडेट करने के लिए कॉल करना पड़ सकता है।

$ घड़ी () : -

इस फ़ंक्शन का उपयोग $ स्कोप पर एक चर में परिवर्तनों का निरीक्षण करने के लिए किया जाता है। यह तीन मानकों को स्वीकार करता है: अभिव्यक्ति, श्रोता और समानता वस्तु, जहां श्रोता और समानता वस्तु वैकल्पिक पैरामीटर हैं।

$ पाचन () -

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

$ आवेदन () -

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


चेतावनी: यह उत्तर केवल एक संभावित समाधान के रूप में प्रदान किया गया है; यह स्पष्ट रूप से सबसे अच्छा समाधान नहीं है, क्योंकि इसमें jQuery की आवश्यकता होती है। इसके बजाय, शुद्ध जावास्क्रिप्ट समाधान पसंद करते हैं।

$(location).attr('href', 'http://.com')




javascript angularjs data-binding