AngularJS में एनजी-रिपीट स्कोप के साथ डायरेक्ट आइसोलेटेड स्कोप


95

मेरे पास एक आइसोलेट-स्कोप वाला निर्देश है (ताकि मैं अन्य स्थानों पर निर्देश का पुन: उपयोग कर सकूं), और जब मैं इस निर्देश का उपयोग करता हूं ng-repeat, तो यह काम करने में विफल रहता है।

मैंने इस विषय पर सभी दस्तावेज और स्टैक ओवरफ्लो के उत्तर पढ़े हैं और मुद्दों को समझा है। मेरा मानना ​​है कि मैंने सभी सामान्य गोचरों से परहेज किया है।

इसलिए मैं समझता हूं कि ng-repeatनिर्देश द्वारा बनाए गए दायरे के कारण मेरा कोड विफल हो जाता है । मेरा खुद का निर्देश एक अलग-अलग दायरे बनाता है और माता-पिता के दायरे में एक वस्तु के लिए दो-तरफ़ा डेटा-बाइंडिंग करता है। मेरा निर्देशन इस बाध्य चर के लिए एक नया ऑब्जेक्ट-वैल्यू असाइन करेगा और यह पूरी तरह से काम करता है जब मेरा निर्देश बिना उपयोग किया जाता है ng-repeat(मूल चर सही तरीके से अपडेट किया गया है)। हालाँकि, ng-repeatअसाइनमेंट के ng-repeatदायरे में एक नया वैरिएबल बनाता है और पैरेंट वैरिएबल में बदलाव नहीं दिखता है। यह सब जैसा मैंने पढ़ा है, उसके आधार पर अपेक्षित है।

मैंने यह भी पढ़ा है कि जब किसी दिए गए तत्व पर कई निर्देश होते हैं, तो केवल एक गुंजाइश बनती है। और उस priorityनिर्देश को परिभाषित करने के लिए प्रत्येक निर्देश में सेट किया जा सकता है जिसमें निर्देश लागू होते हैं; निर्देशों को प्राथमिकता से क्रमबद्ध किया जाता है और फिर उनके संकलन कार्यों को कहा जाता है (शब्द प्राथमिकता के लिए खोज http://docs.angularjs.org/guide/directive पर )।

इसलिए मैं उम्मीद कर रहा था कि मैं यह सुनिश्चित करने के लिए प्राथमिकता का उपयोग कर सकता हूं कि मेरा निर्देशन पहले चलता है और एक अलग-अलग दायरे का निर्माण करता है, और जब ng-repeatरन करता है, तो यह एक गुंजाइश बनाने के बजाय आइसोलेट-स्कोप का फिर से उपयोग करता है जो कि मूल रूप से पेरेंट स्कोप से विरासत में मिला है। ng-repeatप्रलेखन कहा गया है कि प्राथमिकता स्तर पर है कि निर्देश रन 1000। यह स्पष्ट नहीं है कि 1उच्च प्राथमिकता स्तर या निम्न प्राथमिकता स्तर है या नहीं। जब मैंने 1अपने निर्देशन में प्राथमिकता स्तर का इस्तेमाल किया , तो इससे कोई फर्क नहीं पड़ा, इसलिए मैंने कोशिश की 2000। लेकिन इससे चीजें बदतर हो जाती हैं: मेरे दो-तरफा बाइंडिंग बन जाते हैं undefinedऔर मेरा निर्देश कुछ भी प्रदर्शित नहीं करता है।

मैंने अपना मुद्दा दिखाने के लिए एक फील बनाया है । मैंने priorityअपने निर्देशन में सेटिंग पर टिप्पणी की है । मेरे पास नाम ऑब्जेक्ट्स की एक सूची है और एक निर्देश कहा जाता है name-rowजो नाम ऑब्जेक्ट में पहला और अंतिम नाम फ़ील्ड दिखाता है। जब एक प्रदर्शित नाम पर क्लिक किया जाता है, तो मैं चाहता हूं कि यह selectedमुख्य दायरे में एक चर सेट करे । नामों की सरणी, selectedचर को name-rowदो-तरफ़ा डेटा-बाइंडिंग का उपयोग करके निर्देश के पास किया जाता है ।

मुझे पता है कि मुख्य दायरे में कार्यों को कॉल करके इसे कैसे प्राप्त किया जाए। मुझे यह भी पता है कि अगर selectedकिसी अन्य वस्तु के अंदर है, और मैं बाहरी वस्तु से बांधता हूं, तो चीजें काम करेंगी। लेकिन मुझे फिलहाल उन समाधानों में कोई दिलचस्पी नहीं है।

इसके बजाय, मेरे पास जो प्रश्न हैं:

  • मैं ng-repeatएक ऐसा दायरा बनाने से कैसे रोकूँ , जो मूल रूप से मूल दायरे से विरासत में मिला है, और इसके बजाय यह मेरे निर्देशन के अलग-अलग दायरे का उपयोग करता है?
  • 2000मेरे निर्देशन में प्राथमिकता स्तर काम क्यों नहीं कर रहा है?
  • बतरंग का उपयोग करना, क्या यह जानना संभव है कि किस प्रकार का दायरा उपयोग में है?

1
आम तौर पर, आप एक अलग दायरे का उपयोग नहीं करना चाहते हैं यदि आपका निर्देश अन्य निर्देशों के साथ एक ही तत्व पर उपयोग किया जाएगा। जब से आप अपने स्वयं के गुंजाइश गुण बना रहे हैं, और आपको एनजी-रिपीट के साथ काम करने की आवश्यकता है, मैं scope: trueआपके निर्देश का उपयोग करने का सुझाव देता हूं । यह भी देखें (यदि आप पहले से ही नहीं हैं) stackoverflow.com/questions/14914213/… इसके अलावा, सिर्फ इसलिए कि कई जगहों पर एक निर्देश का उपयोग किया जाएगा इसका मतलब यह नहीं है कि हमें स्वचालित रूप से एक अलग गुंजाइश का उपयोग करना चाहिए।
मार्क राजकॉक

मैंने आपके कई उत्तर पढ़े हैं (वे उत्कृष्ट से परे हैं, उन्हें लिखने के लिए धन्यवाद), लेकिन आपके प्रश्नों को पढ़ने के लिए मेरे साथ ऐसा कभी नहीं हुआ है :-)। मैंने पढ़ा कि आपने क्या लिंक किया है। यह मुझे प्रतीत होता है कि आइसोलेट-स्कोप के निर्देश अन्य निर्देशों के साथ मिश्रित नहीं किए जा सकते। मैं इस भावना से सहमत हूं कि इस तरह के निर्देश घटक हैं और इसलिए उन्हें अन्य निर्देशों के साथ मिश्रित होने की आवश्यकता नहीं है। मेरे लिए एक अपवाद (अब तक) होगा ng-repeat। मुझे लगता है कि स्टैंडअलोन निर्देशों के साथ मिश्रण करने में सक्षम होना मूल्यवान है ng-repeat। जारी रखने के लिए ...
दीपक नुलु

ऊपर से जारी ... इसलिए यदि किसी तत्व के लिए एक गुंजाइश के साथ केवल एक निर्देश ng-repeatहोना चाहिए , तो एक गुंजाइश नहीं होनी चाहिए। ng-repeatएक गुंजाइश होने से विशिष्ट उपयोग-मामले के लिए समझ में आता है, इसलिए मैं यह सुझाव नहीं दे रहा हूं कि इसे बदल दिया जाए। इसके बजाय, जैसे मैंने एलेक्स ओसबोर्न के जवाब में टिप्पणी की, मुझे लगता है कि मैं एक दोहराव निर्देश बनाऊंगा जो ng-repeatउस पर आधारित नहीं है जो अपना स्वयं का दायरा नहीं बनाता है। इसके बाद उन निर्देशों को दोहराने के लिए उपयोग किया जा सकता है जिनके अपने अलग-अलग स्कोप हैं। जारी रखने के लिए ...
दीपक नुलु

एक निर्देश को दोहराने वाले कोड को अब यह जानने की जरूरत है कि उपयोग करना है ng-repeatया कस्टम स्कोप-कम रिपीट निर्देश। मुझे लगता है कि यह जानने के लिए "कॉलर" के लिए ठीक है, लेकिन एक "कैली" (निर्देश दोहराया जा रहा है) के लिए ठीक नहीं है यह जानने के लिए कि यह दोहराया जा रहा है या नहीं। जारी रखा जाए ...
दीपक नुलु

यहाँ टिप्पणियों के साथ थोड़ा पागल हो रहा है ... :-) ngRepeat को अपना दायरा बनाना होगा । आपको क्यों लगता है कि आपको यहां एक अलग दायरे की आवश्यकता है?
जोश डेविड मिलर

जवाबों:


203

ठीक है, ऊपर बहुत सारी टिप्पणियों के माध्यम से, मैंने भ्रम की खोज की है। सबसे पहले, स्पष्टीकरण के कुछ बिंदु:

  • ngRepeat आपके चुने हुए अलग-अलग दायरे को प्रभावित नहीं करता है
  • आपके निर्देशों की विशेषताओं पर उपयोग के लिए पैरामीटर एनकैपिट में पास किए गए हैं जो एक प्रोटोटाइप-इनहेरिटेड गुंजाइश का उपयोग करते हैं
  • आपके निर्देश के काम नहीं करने का कारण अलग-अलग दायरे से कोई लेना-देना नहीं है

यहाँ उसी कोड का एक उदाहरण दिया गया है, लेकिन निकाले गए निर्देश के साथ:

<li ng-repeat="name in names"
    ng-class="{ active: $index == selected }"
    ng-click="selected = $index">
    {{$index}}: {{name.first}} {{name.last}}
</li>

यहाँ एक JSFiddle प्रदर्शित है कि यह काम नहीं करेगा। आपको अपने निर्देश के अनुसार सटीक परिणाम मिलते हैं।

यह काम क्यों नहीं करता है? क्योंकि AngularJS में स्कोप्स प्रोटोटाइपिक वंशानुक्रम का उपयोग करते हैं। selectedआपके पैरेंट स्कोप पर मूल्य एक आदिम है । जावास्क्रिप्ट में, इसका मतलब है कि जब बच्चा एक ही मूल्य निर्धारित करता है, तो इसे ओवरराइट किया जाएगा। एंगुलरजेएस स्कोप्स में एक सुनहरा नियम है: मॉडल मान हमेशा उनमें होना चाहिए .। यही है, उन्हें कभी भी आदिम नहीं होना चाहिए। देखें इस तो जवाब में अधिक जानकारी के लिए।


यहाँ एक तस्वीर है जो शुरू में दिखती है।

यहां छवि विवरण दर्ज करें

पहले आइटम पर क्लिक करने के बाद, स्कोप अब इस तरह दिखते हैं:

यहां छवि विवरण दर्ज करें

ध्यान दें कि एक नई selectedसंपत्ति ngRepeat दायरे पर बनाई गई थी। कंट्रोलर स्कोप 003 में बदलाव नहीं किया गया था।

आप शायद अनुमान लगा सकते हैं कि जब हम दूसरे आइटम पर क्लिक करते हैं तो क्या होता है:

यहां छवि विवरण दर्ज करें


तो आपका मुद्दा वास्तव में ngRepeat के कारण नहीं है - यह AngularJS में एक सुनहरा नियम तोड़ने के कारण है। इसे ठीक करने का तरीका बस एक वस्तु संपत्ति का उपयोग करना है:

$scope.state = { selected: undefined };
<li ng-repeat="name in names"
    ng-class="{ active: $index == state.selected }"
    ng-click="state.selected = $index">
    {{$index}}: {{name.first}} {{name.last}}
</li>

यहाँ एक दूसरा JSFiddle भी इस काम को दिखा रहा है।

यहाँ वही है जो स्कोप शुरू में दिखता है:

यहां छवि विवरण दर्ज करें

पहला आइटम क्लिक करने के बाद:

यहां छवि विवरण दर्ज करें

यहां, नियंत्रक गुंजाइश को प्रभावित किया जा रहा है, जैसा कि वांछित है।

इसके अलावा, यह साबित करने के लिए कि यह अभी भी आपके निर्देश के साथ एक अलग दायरे के साथ काम करेगा (क्योंकि, फिर से, इसका आपकी समस्या से कोई लेना-देना नहीं है), यहाँ भी इसके लिए एक JSFiddle है, दृश्य को ऑब्जेक्ट को प्रतिबिंबित करना होगा। आप ध्यान देंगे कि एक आदिम के बजाय एक वस्तु का उपयोग करने के लिए केवल आवश्यक परिवर्तन था ।

शुरू में स्कोप्स:

यहां छवि विवरण दर्ज करें

पहले आइटम पर क्लिक करने के बाद स्कोप्स:

यहां छवि विवरण दर्ज करें

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


आइसोलेट-स्कोप और 2-वे डेटा बाइंडिंग वाले निर्देशों के साथ मेरे प्रयोग मुझे विश्वास .दिलाते हैं कि स्कोप के लिए केवल सुनहरी नियम की आवश्यकता होती है जिसमें प्रोटोटाइपिक वंशानुक्रम होता है। आइसोलेट-स्कोप्स के साथ, जिन वेरिएबल्स में आप रुचि रखते हैं scope: {}, वे डायरेक्टिव में परिभाषा में परिभाषित होते हैं , और इसलिए वे वैरिएबल शुरुआत से ही आइसोलेट-स्कोप में मौजूद होंगे। इसके अलावा, वे माता-पिता के चर का मुखौटा नहीं लगाते हैं क्योंकि अलग-थलग-गुंजाइश मूल रूप से मूल रूप से पैतृक क्षेत्र से विरासत में नहीं मिलती है। यानी मास्क करने के लिए कोई "अभिभावक" गुंजाइश नहीं है।
दीपक नुलु

1
यह भी कहा जाना चाहिए: आपका निर्देश बाल गुंजाइश नहीं बना रहा है, लेकिन इसे आसानी से एक संदर्भ में इस्तेमाल किया जा सकता है जिसके लिए बच्चे की गुंजाइश की आवश्यकता होती है। ngRepeat एक मामला है। तो ट्रांसकॉन्सेक्शन है। मुझ पर भरोसा करो - उपयोग करो .
जोश डेविड मिलर

1
AngularJS Google समूह पर चर्चा जहां @JoshDavidMiller अंत में मेरा भ्रम दूर करने में सक्षम थी!
दीपक नुलु

2
आप लोग इन सभी शांत आरेखों को कहाँ से प्राप्त करते हैं? मैंने एक अन्य उपयोगकर्ता को भी इन्हें पोस्ट करते हुए देखा है।
असद सईदुद्दीन

3
@ असद, मैंने अभी हाल ही में GitHub पर टूल डाला है, इसे पेरी $ स्कोप कहा जाता है ।
मार्क राजकोक

6

सीधे अपने सवालों के जवाब देने से बचने की कोशिश करने के बजाय, निम्नलिखित फिडेल पर एक नज़र डालें:

http://jsfiddle.net/dVPLM/

मुख्य बिंदु यह है कि आप कोणीय के पारंपरिक व्यवहार से लड़ने और बदलने की कोशिश करने के बजाय, आप ng-repeatइसे ओवरराइड करने की कोशिश के विपरीत अपने निर्देश को काम करने के लिए तैयार कर सकते हैं।

अपने टेम्पलेट में:

    <name-row 
        in-names-list="names"
        io-selected="selected">
    </name-row>

आपके निर्देश में:

    template:
'        <ul>' +      
'            <li ng-repeat="name in inNamesList" ng-class="activeClass($index)" >' +
'                <a ng-click="setSelected($index)">' +
'                    {{$index}} - {{name.first}} {{name.last}}' +
'                </a>' +
'            </li>' +
'        </ul>'

आपके सवालों के जवाब में:

  • ng-repeat एक गुंजाइश बनाएगा, आपको वास्तव में इसे बदलने की कोशिश नहीं करनी चाहिए।
  • निर्देशों में प्राथमिकता सिर्फ निष्पादन आदेश नहीं है - देखें: AngularJS: HTML संकलक संकलन के लिए आदेश की व्यवस्था कैसे करता है?
  • बतरंग में, यदि आप प्रदर्शन टैब की जांच करते हैं, तो आप प्रत्येक स्कोप के लिए बंधे हुए भाव देख सकते हैं, और यह देख सकते हैं कि यह आपकी अपेक्षाओं से मेल खाता है या नहीं।

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

मैं अपनी टिप्पणी ऊपर स्पष्ट करना चाहूंगा। मुझे लगता है कि एक निर्देश लिखना संभव है जो इस बारे में चिंता नहीं करता है कि इसका उपयोग किया जा रहा है ng-repeatया नहीं। लेकिन ऐसा प्रतीत होता है कि मुझे निर्देशन के लिए एक फ़ंक्शन में पास होना होगा ताकि यह माता-पिता के दायरे में चर को संशोधित कर सके, बजाय इसके कि निर्देश के अपने दायरे में दो-तरफ़ा बाइंडिंग को म्यूट करने में सक्षम हो। दो तरह से बाध्यकारी और पुन: प्रयोज्य निर्देश मेरी शीर्ष दो पसंदीदा चीजें हैं जो अंगुलरजेएस के बारे ng-repeatमें हैं और मरहम में एक मक्खी साबित हो रही हैं। शायद मैं एक ng-repeatसमतुल्य लिख सकता हूं जो अपना दायरा नहीं बनाता है।
दीपक नुलु
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.