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


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

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

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

myobject.myproperty="new value";

1803
2018-03-13 10:16


मूल


ध्यान रखें कि कोणीय 1.0.0rc1 के बाद से आपको ng-model-instant निर्दिष्ट करना होगा (docs-next.angularjs.org/api/...) अपने मॉडर को तत्काल अपडेट किया गया है। अन्यथा यह धुंध घटना पर अद्यतन किया जाएगा। - Sotomajor
मार्सेलो का लिंक स्पष्ट रूप से टूटा हुआ है, इसलिए यहां फिर से है: github.com/mhevery/angular.js/blob/master/docs/content/guide/... - riffraff
@orian, वह लिंक खराब है। अपडेट किया गया (मुझे लगता है) वही है - docs.angularjs.org/guide/databinding - Kevin Meredith
उन लोगों के लिए जो अभी भी इस प्रश्न को पढ़ रहे हैं, कृपया ध्यान दें कि कोणीय 2.0 ने वेब घटकों के साथ काम करने और नीचे दिए गए उत्तरों में कई मुद्दों को संबोधित करने के लिए कोणीय 1.x के बाद से डाटाबेसिंग के बारे में बताया है। - aug


जवाब:


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

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

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

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

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

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

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

मनुष्य हैं:

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

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

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

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


2660
2018-03-13 23:47



@ मार्क - हां, केओ में आप इसे जोड़ने से पहले अंतिम परिवर्तन घटना के बाद 500 मिलीसेकंड का इंतजार करने के लिए .extend ({throttle: 500}) को जोड़ने के लिए। - Daniel Earwicker
यह पूरा जवाब "महान होने तक 50 एफपीएस प्राप्त करने के अलावा बहुत अच्छा है, उस पर कोई भी प्रदर्शन एक अपशिष्ट है, क्योंकि मानव आंख इसकी सराहना नहीं कर सकती है, इसलिए आप एफपीएस उच्च होने की तुलना में अधिक सामान खींचने से बेहतर हैं।" यह बयान आपके आवेदन के आधार पर पूरी तरह गलत है। आंख निश्चित रूप से 50 से अधिक एफपीएस की सराहना कर सकती है, और वीआर शो के साथ विभिन्न समस्याओं के रूप में (जॉन कारमैक या माइकल एब्राश, विशेष रूप से बाद की जीडीसी 2013 वीआर टॉक से नवीनतम में से किसी एक को पढ़ें), 50 एफपीएस वास्तव में बहुत धीमी है। इसके अलावा, आपका जवाब बहुत अच्छा है। मैं सिर्फ गलत जानकारी फैलाना नहीं चाहता। - Nate Bundy
बस सोच रहा है, अगर आपका ऐप ट्विटर या टिप्पणी थ्रेड / फोरम जैसा है, और आप कोणीय के आधार पर अनंत स्क्रॉलिंग लागू करते हैं, तो आप "जानकारी के 2000 टुकड़े" "सीमा" में भाग सकते हैं। एक टिप्पणी में लेखक के नाम, प्रोफाइल आईएमजी, सामग्री, डेटाटाइम आदि के लिए आसानी से कई चर हो सकते हैं। साथ ही, कहें कि हमारे पास सभी टिप्पणियों / पोस्टों को संग्रहीत करने के लिए एक विशाल सरणी है, हर गंदे जांच के लिए इस सरणी की स्कैनिंग की आवश्यकता होगी, मैं सही हूँ? इससे ब्राउजर को थोड़ी देर तक खराब कर दिया जाएगा जो खराब उपयोगकर्ता अनुभव है। उचित प्रदर्शन सुनिश्चित करने के लिए हम इस मामले में क्या करते हैं? - Lucas
बयान को आसानी से उल्टा में कहा जा सकता है क्योंकि "गंदा जांच एक समस्या के लिए एक चालाक सुविधा है जो नॉकआउट नहीं है"। ES6 अवलोकनों का उपयोग कर रहा है और कोणीय गंदे जांच से छुटकारा पा रहा है। वास्तविक दुनिया ने इस जवाब को पकड़ लिया और इसे झूठा दिखाया। - conical
"50 एमएस से भी तेज कुछ भी इंसानों के लिए अतिसंवेदनशील है" सच नहीं है। परीक्षण में हमने पाया है कि हमारे ग्राहक आसानी से 50ms अपडेट विलंबता (20fps) और 16.6ms अद्यतन विलंबता (60fps) के बीच अंतर कर सकते हैं। पूर्व गति पर चल रहे दृश्य लगातार गरीबों को "यह कैसा महसूस करते हैं" रेटिंग प्राप्त करते हैं, भले ही लोग जानबूझकर फ़्रेमेट पंजीकृत न करें। - Crashworks


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

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

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

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

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

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

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


308
2017-08-22 13:28



हाँ मैं यह दूसरा। हमारी ऐप की प्राथमिक ज़िम्मेदारी अलग-अलग इकाइयों के बीच कनेक्शन प्रदर्शित करना है। किसी दिए गए पृष्ठ में 10 अनुभाग हो सकते हैं। प्रत्येक खंड में एक टेबल है। प्रत्येक तालिका में 2-5 टाइपहेड फ़िल्टर होते हैं। प्रत्येक तालिका में 2-5 कॉलम होते हैं, प्रत्येक में 10 पंक्तियां होती हैं। बहुत जल्दी हम perf मुद्दों में भागते हैं, और "समान चाल" विकल्पों के साथ जा रहे हैं। - Scott Silvi
क्या यह कहना उचित है कि कोणीय न केवल डेटा बाइंडिंग के बारे में है और कुछ ऐप्स इस सुविधा का उपयोग दूसरों के उद्धरण के कारणों के लिए नहीं करना चाहते हैं? मुझे लगता है कि डीआई और मॉड्यूलरिटी का दृष्टिकोण खुद के लायक है; जादू ऑटो-बाइंडिंग अच्छा है लेकिन हर मौजूदा कार्यान्वयन में प्रदर्शन के व्यापार-बंद हैं। कोणीय का तरीका सीआरयूडी वेब ऐप्स के बहुमत के लिए तर्कसंगत रूप से बेहतर है, और लोग इसे चरम पर ले जाने की कोशिश करके दीवार को मार रहे हैं। इवेंट सुनने का एक वैकल्पिक तरीका होना अच्छा लगेगा, लेकिन हो सकता है कि यह मूल रूप से एक ही ढांचे के लिए जटिल हो? - Jason Boyd
कोणीय के पास इस समस्या से मदद करने के लिए अब एक तरीका है और बाध्यकारी है। इसके अलावा अब आपके पुनरावर्तक स्रोत के लिए अनुक्रमणिका है, जो आपको संपूर्ण सामग्री के लिए डोम के पुनर्निर्माण के बिना सूची को संशोधित करने देता है। - Mithon
@MW। ईमानदारी से मैंने सोचा कि एक बार कोर में था। लेकिन ऐसा लगता है कि यह नहीं है। यह केवल कुछ ऐसा है जो आप अपने निर्देश लिखते समय कर सकते हैं, मूल रूप से उन्हें देखे बिना सामान को जोड़ना। हालांकि इसके लिए एक ux mod है: github.com/pasvaz/bindonce - Mithon
किसी को पढ़ने के लिए भविष्य से एक चिल्लाओ: एक बार बाध्यकारी अब कोणीय v1.3 में एक मुख्य विशेषता है, और यहां पढ़ें: docs.angularjs.org/guide/expression - Nobita


गंदा जांच करके $scope वस्तु

कोणीय एक सरल रखता है array में देखने वालों की $scope वस्तुओं। यदि आप किसी का निरीक्षण करते हैं $scope आप पाएंगे कि इसमें एक है array बुलाया $$watchers

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

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

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

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

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

    $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

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

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

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

10 $digest() iterations reached. Aborting!

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

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

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

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

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

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

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

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

या

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

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

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

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

142
2018-06-02 12:31



मैं असहमत हूं कि कहा गया जवाब शीर्ष पर होना चाहिए; किसी विशिष्ट प्रश्न के लिए कुछ जानने और प्रासंगिक / विस्तृत उत्तर लिखने के बीच एक अंतर है। प्रशंसा पाने के बेहतर तरीके हैं। वैसे भी .. - user2864740
मुझे संदेह नहीं है कि यह सच है, लेकिन सवाल प्रश्न और उत्तर के जवाब :) - user2864740
अच्छा जवाब यह बताता है कि गंदे-जांच कैसे व्यवहार करती है और इसका वास्तव में मूल्यांकन क्या होता है, मिस्को के जवाब में एक बात बहुत स्पष्ट नहीं थी। - bitstrider
शानदार और विस्तृत उत्तर। @superluminary, इस तरह के उत्तर के लिए धन्यवाद। इसके अलावा, इस उत्तर को पढ़ने के बाद, मैं इस बिंदु पर आ गया कि हमें गैर-बेवकूफ अभिव्यक्ति को अभिव्यक्ति के रूप में नहीं जोड़ना चाहिए। - Mangu Singh Rajpurohit
यह शीर्ष जवाब होना चाहिए - Alexandre Bourlier


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

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

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


77
2018-03-13 21:01



लागू विधि कब ट्रिगर की जाती है? - numan salati
@EliseuMonar पाचन लूप कुछ घटनाओं के परिणामस्वरूप चलाता है या $ आवेदन () को कॉल करता है, इसे समय-समय पर टाइमर पर आधारित नहीं कहा जाता है। देख AngularJS के $ घड़ी समारोह कैसे काम करता है? तथा AngularJS में बाध्यकारी और पचाने का काम कैसे करता है? - remi
@remi, मैं AngularJS के अंतिम संस्करण के बारे में चिंतित नहीं हूँ। क्या वे पहले से ही प्रॉक्सी या ऑब्जेक्ट.ब्सर्व का उपयोग कर रहे हैं? यदि नहीं, तो वे अभी भी गंदे जांच युग में हैं, जो कि मॉडल विशेषताएँ बदल गई हैं या नहीं, यह देखने के लिए एक समय लूप बनाता है। - Eliseu Monar dos Santos
मैंने पढ़ा है कि पाचन अधिकतम दस गुना चलाएगा sitepoint.com/understanding-angulars-apply-digest - user137717


मैंने थोड़ी देर के लिए यह खुद को सोचा। सेटर्स के बिना कैसे करता है AngularJS में परिवर्तन नोटिस $scope आपत्ति? क्या यह उन्हें मतदान करता है?

यह वास्तव में क्या करता है यह है: मॉडल को संशोधित करने वाला कोई भी "सामान्य" स्थान पहले से ही हिट से बुलाया गया था AngularJS, इसलिए यह स्वचालित रूप से कॉल करता है $apply आपके कोड के चलने के बाद आपके लिए। कहें कि आपके कंट्रोलर की एक विधि है जो जुड़ी हुई है ng-click कुछ तत्व पर। इसलिये AngularJS उस विधि को आपके लिए एक साथ बुलाता है, इसे करने का मौका होता है $apply उचित जगह में इसी तरह, अभिव्यक्तियों के लिए जो विचारों में सही दिखाई देते हैं, उनके द्वारा निष्पादित किया जाता है AngularJS तो यह करता है $apply

जब दस्तावेज़ कॉल करने के बारे में बात करता है $apply कोड के लिए मैन्युअल रूप से के बाहर AngularJS, यह कोड के बारे में बात कर रहा है, जो दौड़ते समय, से नहीं निकलता है AngularJS कॉल स्टैक में खुद ही।


57
2017-09-03 17:45





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

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

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

enter image description here

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

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

enter image description here

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

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

निष्कर्ष

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

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


29
2018-05-20 13:33





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

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

  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;
 };

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

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

19
2018-05-22 18:18