AngularJS: $ अवलोकन और $ घड़ी विधियों के बीच अंतर


378

मुझे पता है कि दोनों ही Watchersऔर AngularJS Observersमें $scopeपरिवर्तन के रूप में जल्द ही गणना कर रहे हैं । लेकिन समझ नहीं सका कि वास्तव में दोनों के बीच अंतर क्या है।

मेरी प्रारंभिक समझ यह है कि Observersकोणीय अभिव्यक्तियों के लिए गणना की जाती है जो HTML तरफ स्थितियां हैं जहां फ़ंक्शन Watchersनिष्पादित होने $scope.$watch()पर निष्पादित किया जाता है। क्या मैं ठीक से सोच रहा हूँ?


1
आपका संपादन मददगार नहीं है और थोड़ा विरोधी है। कृपया वास्तविक सहायता के लिए यहां आने वाले अन्य लोगों पर विचार करें।
स्मालोन

@ सेमलोन बदल गया। धन्यवाद और क्षमा करें!
अबिलाश

Ries कोई चिंता नहीं। ठीक करने के लिए धन्यवाद।
स्मालोन

जवाबों:


608

$ अवलोकन () गुण वस्तुपर एक विधि है, और इस तरह, इसका उपयोग केवल DOM विशेषता के मूल्य परिवर्तन को देखने / देखने के लिए किया जा सकता है। इसका उपयोग केवल निर्देशों के अंदर किया जाता है। जब आप एक डोम विशेषता को देखने / देखने की आवश्यकता हो, जिसमें इंटरपोलेशन (अर्थात, {{}}}) का उपयोग करने पर $ अवलोकन का उपयोग करें।
जैसे,attr1="Name: {{name}}"फिर एक निर्देश मेंattrs.$observe('attr1', ...):।
(यदि आप कोशिशscope.$watch(attrs.attr1, ...)करते हैं कि यह {{}} s के कारण काम नहीं करेगा - आपको मिल जाएगाundefined।) बाकी सब चीजों के लिए $ घड़ी का उपयोग करें।

$ घड़ी () अधिक जटिल है। यह एक "अभिव्यक्ति" का अवलोकन / देख सकता है, जहां अभिव्यक्ति या तो एक फ़ंक्शन या एक स्ट्रिंग हो सकती है। यदि अभिव्यक्ति एक स्ट्रिंग है, तो यहएक फ़ंक्शन में $ parse 'd (यानी, एक कोणीय अभिव्यक्ति के रूप में मूल्यांकन) है। (यह ऐसा फ़ंक्शन है जिसे हर पाचन चक्र कहा जाता है।) स्ट्रिंग अभिव्यक्ति में {{}} का नहीं हो सकता है। $ घड़ी स्कोप ऑब्जेक्टपर एक विधि है, इसलिए इसका उपयोग किया जा सकता है / बुलाया जा सकता है, जहां भी आपके पास गुंजाइश ऑब्जेक्ट तक पहुंच है, इसलिए

  • एक नियंत्रक - किसी भी नियंत्रक - एनजी-व्यू, एनजी-नियंत्रक या एक निर्देशक नियंत्रक के माध्यम से बनाया गया
  • एक निर्देशन में एक लिंकिंग फ़ंक्शन, क्योंकि इसमें एक गुंजाइश भी है

क्योंकि स्ट्रिंग्स का मूल्यांकन कोणीय भावों के रूप में किया जाता है, $ घड़ी का उपयोग अक्सर तब किया जाता है जब आप किसी मॉडल / स्कोप प्रॉपर्टी को देखना / देखना चाहते हैं। जैसे, attr1="myModel.some_prop"फिर किसी कंट्रोलर या लिंक फंक्शन में: scope.$watch('myModel.some_prop', ...)या scope.$watch(attrs.attr1, ...)(या scope.$watch(attrs['attr1'], ...))।
(यदि आप कोशिश attrs.$observe('attr1')करेंगे तो आपको स्ट्रिंग मिल जाएगी myModel.some_prop, जो शायद आप नहीं चाहते हैं।)

जैसा कि @ PrimosK के उत्तर पर टिप्पणियों में चर्चा की गई है, सभी $ अवलोकन और $ घड़ियाँ हर पाचन चक्र की जाँच की जाती हैं

पृथक स्कोप वाले निर्देश अधिक जटिल हैं। यदि '@' सिंटैक्स का उपयोग किया जाता है, तो आप एक DOM विशेषता देख सकते हैं या $ देख सकते हैं, जिसमें प्रक्षेप (यानी, {{}} 's) हैं। (यह $ घड़ी के साथ काम करने का कारण है क्योंकि '@' सिंटैक्स हमारे लिए प्रक्षेप करता है, इसलिए $ घड़ी बिना {{}} के स्ट्रिंग को देखती है।) यह याद रखना आसान बनाने के लिए कि कब, किसका उपयोग करने का सुझाव है। इस मामले के लिए भी $ अवलोकन करें।

इस सब का परीक्षण करने में मदद करने के लिए, मैंने एक प्लंकर लिखा है जो दो निर्देशों को परिभाषित करता है। एक ( d1) नया स्कोप नहीं d2बनाता , दूसरा ( ) एक अलग स्कोप बनाता है। प्रत्येक निर्देश में समान छह विशेषताएँ हैं। प्रत्येक विशेषता $ अवलोकन और $ watch'ed दोनों है।

<div d1 attr1="{{prop1}}-test" attr2="prop2" attr3="33" attr4="'a_string'"
        attr5="a_string" attr6="{{1+aNumber}}"></div>

लिंक फ़ंक्शन में $ अवलोकन और $ घड़ी के बीच अंतर देखने के लिए कंसोल लॉग को देखें। फिर लिंक पर क्लिक करें और देखें कि कौन से $ अवलोकन और $ घड़ियाँ क्लिक हैंडलर द्वारा किए गए संपत्ति परिवर्तनों से शुरू होती हैं।

ध्यान दें कि जब लिंक फ़ंक्शन चलता है, तो {{}}} वाले किसी भी गुण का मूल्यांकन अभी तक नहीं किया गया है (इसलिए यदि आप विशेषताओं की जांच करने का प्रयास करते हैं, तो आपको मिलेगा undefined)। प्रक्षेपित मूल्यों को देखने का एकमात्र तरीका $ अवलोकन (या '@' के साथ एक अलग गुंजाइश का उपयोग करके $ घड़ी) का उपयोग करना है। इसलिए, इन विशेषताओं के मूल्यों को प्राप्त करना एक अतुल्यकालिक ऑपरेशन है। (और यही कारण है कि हमें $ निरीक्षण और $ घड़ी कार्यों की आवश्यकता है।)

कभी-कभी आपको $ अवलोकन या $ घड़ी की आवश्यकता नहीं होती है। जैसे, यदि आपकी विशेषता में कोई संख्या या बूलियन (स्ट्रिंग नहीं) है, तो बस एक बार इसका मूल्यांकन करें: attr1="22"तो, कहें, आपका लिंकिंग फ़ंक्शन var count = scope.$eval(attrs.attr1):। यदि यह सिर्फ एक निरंतर स्ट्रिंग है - attr1="my string"- तो बस attrs.attr1अपने निर्देश में उपयोग करें ($ eval () की कोई आवश्यकता नहीं)।

$ वॉच भावों के बारे में वोज्टा का गूगल समूह पोस्ट भी देखें ।


13
महान व्याख्या! +1
प्रिमोस

4
बहुत बढ़िया जवाब! क्या आपके पास विचार है कि इसके बजाय ng-src/ng-hrefउपयोग क्यों करें ? attr.$observescope.$watch
ओकम

4
AngularJS पोप के लिए +1! हर बार जब मैं अपनी नवीनतम कोणीय समस्या के बारे में कुछ जानकारी के लिए स्टैक खोजता हूं, तो मैं निश्चित रूप से @MarkRajcok के उत्तर को पढ़ता हूं।
GFoley83

1
शानदार प्रतिक्रिया के लिए धन्यवाद। गुंजाइश। $ eval (आइटम) वास्तव में मददगार है। यदि आइटम एक जस स्ट्रिंग है, तो यह एक जसन ऑब्जेक्ट में बदल जाती है।
bnguyen82

5
@tamakisquare, @सिंटैक्स का उपयोग करते समय वे विनिमेय होते हैं । मेरा मानना ​​है कि कोई प्रदर्शन अंतर नहीं है (लेकिन मैंने वास्तविक स्रोत कोड को नहीं देखा है)।
मार्क राजकोक

25

अगर मैं आपके सवाल को सही समझ रहा हूँ तो आप पूछ रहे हैं कि क्या अंतर है अगर आप श्रोता कॉलबैक को रजिस्टर करते हैं $watchया यदि आप इसे करते हैं $observe

$watchजब कॉल किया जाता है तो कॉलबैक रजिस्टर को निकाल दिया जाता $digestहै।

कॉलबैक $observeजिसे तब पंजीकृत किया जाता है, जब विशेषताओं में मूल्य परिवर्तन होते हैं, जिसमें प्रक्षेप (जैसे attr="{{notJetInterpolated}}") होते हैं।


निर्देश के अंदर आप दोनों को बहुत समान तरीके से उपयोग कर सकते हैं:

    attrs.$observe('attrYouWatch', function() {
         // body
    });

या

    scope.$watch(attrs['attrYouWatch'], function() {
         // body
    });

3
दरअसल, चूंकि प्रत्येक परिवर्तन $digestचरण में परिलक्षित होता है , इसलिए यह मान लेना सुरक्षित है कि $observeकॉलबैक को कॉल किया जाएगा $digest। और $watchकॉलबैक भी कहा जाएगा $digestलेकिन जब भी मूल्य में बदलाव किया जाता है। मुझे लगता है कि वे ठीक उसी काम को करते हैं: "एक्सप्रेशन देखें, कॉलबैक वैल्यू में बदलाव करें"। डेवलपर को भ्रमित न करने के लिए कीवर्ड अंतर संभवतः सिंटैक्टिक शुगर है।
उमूर कोंटाचार

1
@fastreload, मैं आपकी टिप्पणी से पूरी तरह सहमत हूँ .. बहुत अच्छा लिखा है!
प्रिमोस

@fastreload ... अद्भुत विवरण के लिए धन्यवाद। अगर मुझे सही तरीके से समझ में आया, तो ऑब्जर्वर कोणीय अभिव्यक्तियों के लिए हैं। क्या मैं सही हू?
अबिलाश

@PrimosK: आपको मेरी पिछली टिप्पणी के लिए जोड़ना।
अबिलाश

2
@ अब्लाश पर्यवेक्षक डोम विशेषताओं को देखने के लिए हैं, न कि केवल अभिव्यक्ति के लिए। इसलिए यदि आप अपने द्वारा विशेषता मान को बदलते हैं, तो यह अगले पाचन चक्र में परिलक्षित होगा।
उमुर कोंटाची

1

मुझे लगता है कि यह बहुत स्पष्ट है:

  • $ अवलोकन का उपयोग निर्देशों के कार्य को जोड़ने में किया जाता है।
  • अपने मूल्यों में किसी भी बदलाव को देखने के लिए गुंजाइश पर $ घड़ी का उपयोग किया जाता है।

ध्यान रखें : दोनों फ़ंक्शन के दो तर्क हैं,

$observe/$watch(value : string, callback : function);
  • मान : हमेशा देखे गए तत्व (एक स्कोप के चर का नाम या निर्देश की विशेषता का नाम देखा जाना) का एक स्ट्रिंग संदर्भ है
  • कॉलबैक : फ़ंक्शन को फ़ॉर्म का निष्पादित किया जाना हैfunction (oldValue, newValue)

मैंने एक बना दिया है plunker, इसलिए आप वास्तव में उनके दोनों उपयोग पर समझ प्राप्त कर सकते हैं। मैंने गिरगिट सादृश्य का उपयोग चित्र बनाने में आसान बनाने के लिए किया है।


2
यह इसके उपयोग के बारे में बहुत स्पष्ट है। पर सवाल क्यों था। मार्क ने इसे खूबसूरती से अभिव्यक्त किया है।
अबिलाश

3
मुझे लगता है कि परमों को स्विच किया जा सकता है - यह न्यूवैल्यू पास करने के लिए प्रकट होता है, फिर ओल्डवैल्यू टू अटैंड्स। $ अवलोकन ()। । ।
विस्फ़ोटक

0

$ वॉच $ वॉच से अलग क्यों है?

वॉचएक्सप्रेशन का मूल्यांकन किया जाता है और पिछले मूल्य की तुलना में प्रत्येक डाइजेस्ट () चक्र होता है, अगर वॉचएक्सप्रेशन मान में कोई परिवर्तन होता है, तो वॉच फ़ंक्शन कहा जाता है।

प्रक्षेपित मूल्यों के लिए $ अवलोकन विशिष्ट है। यदि किसी निर्देश के गुण मान को प्रक्षेपित किया जाता है, उदाहरण के लिए dir-attr="{{ scopeVar }}", निरीक्षण फ़ंक्शन केवल तभी कहा जाएगा जब प्रक्षेपित मान सेट किया जाता है (और इसलिए जब $ डाइजेस्ट ने पहले ही निर्धारित कर लिया है कि अपडेट किए जाने की आवश्यकता है)। मूल रूप से प्रक्षेप के लिए पहले से ही एक द्रष्टा है, और $ फंक्शन का पालन करते हैं।

संकलन में $ अवलोकन और $ सेट देखें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.