2013-10-15 4 views
10

मेरे पास निम्न कोड है, जिसे http://jsfiddle.net/garukun/u69PT/ पर भी जोड़ा जा सकता है।कोणीयजेएस: माता-पिता का दायरा निर्देश में अद्यतन नहीं किया गया है (अलग-अलग दायरे के साथ) दो तरह बाध्यकारी

दृश्य:

<div data-ng-app="testApp"> 
    <div data-ng-controller="testCtrl"> 
     <strong>{{pkey}}</strong> 
     <span data-test-directive data-parent-item="pkey" 
      data-parent-update="update(pkey)"></span> 
    </div> 
</div> 

जे एस:

var testApp = angular.module('testApp', []); 

testApp.directive('testDirective', function ($timeout) { 
    return { 
     scope: { 
      key: '=parentItem', 
      parentUpdate: '&' 
     }, 
     replace: true, 
     template: '<div><p>{{key}}</p>' + 
      '<button data-ng-click="lock()">Lock</button>' + 
      '</div>', 
     controller: function ($scope, $element, $attrs) { 
      $scope.lock = function() { 
       $scope.key = 'D+' + $scope.key; 
       console.log('DIR :', $scope.key); 

       // Expecting $scope.$parent.pkey to have also been 
       // updated before invoking the next line. 
       $scope.parentUpdate(); 
       // $timeout($scope.parentUpdate); // would work. 
      }; 
     } 
    }; 
}); 

testApp.controller('testCtrl', function ($scope) { 
    $scope.pkey = 'golden'; 
    $scope.update = function (k) { 
     // Expecting local variable k, or $scope.pkey to have been 
     // updated by calls in the directive's scope. 
     console.log('CTRL:', $scope.pkey, k); 
     $scope.pkey = 'C+' + k; 
     console.log('CTRL:', $scope.pkey); 
    }; 
}); 

मूल रूप से, मैं एक अलग क्षेत्र के साथ निर्देश, जिसमें मैं दो तरह से एक संपत्ति के लिए बाध्य कर रहा हूँ (key) सेट कर रहा हूं अभिभावक दायरे (पीकी) से, और माता-पिता के दायरे के संदर्भ में एक विधि (parentUpdate) को भी कॉल करने के लिए।

अब, निर्देश में एनजी-क्लिक ईवेंट हैंडलर के दौरान, मैं पैरेंट अपडेट विधि का आह्वान करना चाहता हूं और कुछ अंदर करना चाहता हूं। जब मैं उस विधि का आह्वान कर रहा हूं, तो मैं अपने माता-पिता के दायरे के मॉडल को अद्यतन करने की उम्मीद कर रहा हूं। लेकिन हकीकत में, यह नहीं है, और यह मुझे परेशान कर रहा है।

शायद यह मध्य में कुछ खोए गए $ पाचन चक्रों की वजह से है, क्योंकि $ टाइमआउट के साथ पैरेंट अपडेट कॉल को लपेटने की अपेक्षा की जाएगी।

क्या कोई गायब होने पर कुछ प्रकाश डाल सकता है? या पेरेंट अद्यतन सही तरीके से कैसे पहुंचाया जाए?

+0

ठीक है, तो थोड़ा सा लक्ष्यीकरण ... आप सोच रहे हैं कि '$ scope.key = 'D +' + $ scope.key;' 'lock() 'फ़ंक्शन से' कोई प्रभाव नहीं प्रतीत होता है , सही? – jandersen

उत्तर

25

ठीक है, मैं इस पर एक दरार लेने जा रहा हूं ... ऐसा लगता है कि आप $digest चक्र से पहले पृथक बच्चे और पैरेंट चर दोनों को बदल रहे हैं जहां द्वि-दिशा तर्क दोनों को सिंक करता है। यहां विवरण दिया गया है:

  1. पहले अपने lock() फ़ंक्शन को बटन पर क्लिक करके निष्पादित किया जाता है। यह पृथक $scope.key चर अद्यतन करता है। नोट: यह तुरंत पैरेंट $scope.pKey अपडेट करें; जो आमतौर पर अगले $digest चक्र पर होता है लेकिन इस मामले में नहीं होता है। पढ़ें ...
  2. lock() के भीतर आप parentUpdate() पर कॉल कर रहे हैं जो माता-पिता के $scope.pKey चर को अद्यतन करता है।
  3. फिर $digest चक्र निष्पादित करता है। जब यह माता-पिता के दायरे के लिए रास्ता तय करता है तो $scope.pKey में परिवर्तन सही ढंग से पता चला है।
  4. $scope.pKey में परिवर्तन watch() को ट्रिगर करता है जो अलग-अलग दायरे में द्वि-दिशात्मक बाध्यकारी द्वारा बनाया गया था। These lines महत्वपूर्ण हैं ..
  5. watch() पृथक गुंजाइश द्वारा निर्मित यह जांचता है कि क्या यह द्वि-दिशात्मक बाध्यकारी के लिए मूल्य है माता-पिता के मूल्य के साथ समन्वयित है। यदि यह नहीं है (और यह इस परिदृश्य में नहीं है) तो माता-पिता का मान अलग-अलग दायरे पर कॉपी किया गया है, भले ही अलग-अलग दायरे का मूल्य भी बदल गया हो और वास्तव में पहले बदल दिया गया हो।

Misko's famous post on Angular data-binding$digest चक्र दृष्टिकोण के लाभों का वर्णन है। जो आप यहां देख रहे हैं वह $digest के सहारे को बदलने के दृष्टिकोण का एक सचेत दुष्प्रभाव है, क्योंकि स्रोत कोड टिप्पणी कहती है, parent changed and it has precedence ... और इसका मतलब है कि आपके अलग-अलग दायरे में परिवर्तन खो गया है।

$timeout() दृष्टिकोण आप ऊपर उल्लेख किया पहले $digest चक्र है जो उसे अपने जनक गुंजाइश के लिए सफलतापूर्वक कॉपी होना होगा और फिर बुला अनुमति देता में केवल अलग-अलग दायरे के मान बदलकर इस मुद्दे से बचा जाता है parentUpdate()

$compile documentation का कहना है:

अक्सर अभिव्यक्ति के माध्यम से और अभिभावक के दायरे से अलग-अलग दायरे से डेटा पास करना वांछनीय है, यह अभिव्यक्ति रैपर एफएन में स्थानीय चर नामों और मानों का नक्शा पास करके किया जा सकता है। उदाहरण के लिए, यदि अभिव्यक्ति वृद्धि (राशि) है तो हम स्थानीय एफएन को स्थानीय एफएन ({राशि: 22}) के रूप में कॉल करके राशि मान निर्दिष्ट कर सकते हैं।

इसका मतलब यह है, कदम # 2 पर आप एक वस्तु नक्शा इस तरह के माध्यम से pkey के लिए अपने मूल्य प्रेषित कर सकता:

parentUpdate({pkey: 'D+' + $scope.key }) 

यहाँ अद्यतन बेला है: http://jsfiddle.net/KbYcr/

+0

स्पष्टीकरण के लिए धन्यवाद, यह वास्तव में मददगार है! जबकि मैं समझता हूं कि यह $ पाचन चक्र के डिजाइन के कारण है। मैं टाइमआउट फ़ंक्शन का आह्वान किए बिना माता-पिता के दायरे की संपत्ति के शीर्ष पर अलग-अलग दायरे के गुणों का निर्माण करने का एक तरीका ढूंढ रहा हूं। और इस मामले में, चूंकि हम पहले से ही एक पाचन चक्र में हैं, हम अब $ पाचन या $ लागू नहीं कर सकते हैं। आदर्श रूप में, मैं evalAsync का आह्वान करना चाहता हूं, लेकिन ऐसा लगता है कि यह भी काम नहीं करता है। अगर कोणीय की आस्तीन में एक चाल हो सकती है जो इस डिजाइन को बाईपास कर सकती है, तो यह बहुत ही शानदार होगा। – Steve

+0

मुझे लगता है कि इस तरह की एक चाल है :-) मैंने अभी जवाब के साथ अपना जवाब अपडेट किया है और एक मामूली बदलाव के साथ एक नया जेएसफ़ाइल दिखाया है। – jandersen

+0

उत्कृष्ट स्पष्टीकरण और उदाहरण। बहुत धन्यवाद! –

0

$scope.$apply() बजाय $scope.$digest() का उपयोग करना भी काम करता है यह रूटस्कोप पर डाइजेस्ट को भी ट्रिगर करेगा।

संबंधित मुद्दे