AngularJS - बच्चे के दायरे में प्रवेश


110

यदि मेरे पास निम्नलिखित नियंत्रक हैं:

function parent($scope, service) {
    $scope.a = 'foo';

    $scope.save = function() {
        service.save({
            a:  $scope.a,
            b:  $scope.b
        });
    }
}

function child($scope) {
    $scope.b = 'bar';
}

बाहर parentपढ़ने के लिए उचित तरीका क्या bहै child? यदि यह परिभाषित करने के लिए आवश्यक है bमें parent, यह अर्थ की दृष्टि से गलत सोचते हैं कि बनाने कि नहीं होगा bएक संपत्ति से संबंधित कुछ का वर्णन करता है childऔर नहीं parent?

अद्यतन: इसके बारे में आगे सोचने पर, यदि एक से अधिक बच्चे होते हैं, तो bयह एक संघर्ष पैदा करेगा parentजिसके bलिए उन्हें पुनः प्राप्त करना है। मेरा सवाल बना हुआ है, इससे पहुंचने का उचित तरीका क्या bहै parent?


1
इसके अलावा, सुनिश्चित करें कि आप इसे पढ़ते हैं: stackoverflow.com/questions/14049480/… कोणीयज में स्कोप और वंशानुक्रम का एक बहुत अच्छा और गहन अवलोकन।
मार्टिज़न

जवाबों:


162

AngularJS में स्कोप्स प्रोटोोटाइपल इनहेरिटेंस का उपयोग करते हैं, जब एक बच्चे के दायरे में एक संपत्ति की तलाश करते हैं तो दुभाषिया बच्चे से शुरू होने वाली प्रोटोटाइप श्रृंखला को देखेगा और माता-पिता को तब तक जारी रखेगा जब तक कि वह संपत्ति का पता नहीं लगाता है, दूसरे तरीके से नहीं।

इस मुद्दे पर वोज्टा की टिप्पणियों की जाँच करें https://groups.google.com/d/msg/angular/LDNz_TQQiNE/ygYrSvdI0A0J

संक्षेप में: आप माता-पिता के दायरे से चाइल्ड स्कोप तक नहीं पहुँच सकते।

आपके समाधान:

  1. माता-पिता में गुणों को परिभाषित करें और उन्हें बच्चों से एक्सेस करें (ऊपर लिंक पढ़ें)
  2. राज्य साझा करने के लिए एक सेवा का उपयोग करें
  3. घटनाओं के माध्यम से डेटा पास करें। $emitरूट स्कोप तब तक अभिभावकों को ईवेंट भेजता है $broadcastऔर ईवेंट को नीचे की ओर भेजता है। इससे आपको चीजों को शब्दबद्ध रूप से सही रखने में मदद मिल सकती है।

8
इसके अलावा $ emit और $ ब्रॉडकास्ट के बीच का अंतर वह है जहाँ $ emit रद्द-सक्षम और $ ब्रॉडकास्ट न हो।
अज़री जमील

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

धन्यवाद। एक अन्य विकल्प localStorageजैसे निर्भरता के साथ हो सकता है ngStorage
आकाश

81

जबकि इस मामले को संभालने के लिए jm- का उत्तर सबसे अच्छा तरीका है, भविष्य के संदर्भ के लिए यह संभव है कि गुंजाइश के $ $ चाइल्डहेड, $$ चाइल्डटेल, $$ नेक्स्टबीलिंग और $$ प्रबलित सदस्यों का उपयोग करके बाल स्कोप का उपयोग किया जाए। इनका दस्तावेजीकरण नहीं किया गया है, इसलिए वे बिना किसी नोटिस के बदल सकते हैं, लेकिन वे वहाँ हैं यदि आपको वास्तव में स्कोप को पार करने की आवश्यकता है।

// get $$childHead first and then iterate that scope's $$nextSiblings
for(var cs = scope.$$childHead; cs; cs = cs.$$nextSibling) {
    // cs is child scope
}

बेला


49

आप यह कोशिश कर सकते हैं:

$scope.child = {} //declare it in parent controller (scope)

फिर चाइल्ड कंट्रोलर (स्कोप) में जोड़ें:

var parentScope = $scope.$parent;
parentScope.child = $scope;

अब माता-पिता की पहुंच बच्चे के दायरे तक है।


1
बहुत साफ और सीधा। इसे जोड़ने के लिए बस यह महसूस करें कि कोई बंधन नहीं है, जब आप इसे घोषित करते हैं जैसे कि पैरेंटस्कोप के ऊपर। चिल्ड उस समय चिल्ड स्कोप पकड़ रहा है। इसे हल करने के लिए आप $ गुंजाइश जोड़ सकते हैं। $ घड़ी (फ़ंक्शन () {parentScope.child = $ गुंजाइश}); ताकि हर पचने के बाद यह नए दायरे को अभिभावक तक पहुंचाए। यदि आप html में विज़ुअल्स के लिए चाइल्ड स्कोप में से किसी का उपयोग कर रहे हैं, तो पैरेंट एंड पर आपको इसके चाइल्ड वैरिएबल पर एक घड़ी जोड़ने की आवश्यकता होगी और इसे स्कोप को अपडेट करने के लिए कहेंगे: $ स्कोप। $ वॉच ('चाइल्ड', फंक्शन) ) {$ गुंजाइश। $ evalAsync ();}); । आशा है कि यह किसी को कुछ समय बचाता है!
IfTueue

2
@ यदि मुझे विश्वास है कि एक $ घड़ी () की आवश्यकता नहीं है। ये वस्तुएं हैं और वे संदर्भ से गुजरती हैं।
स्वनिधि

2
@Swanidhi = मुझे पता है कि आपका क्या मतलब है और मैंने ऐसा सोचा था लेकिन यह तब काम नहीं आया जब मैं टिप्पणी लिखने के समय प्रयोग कर रहा था। इसके लायक यह है कि मैं इसे एमिट / ब्रॉडकास्टिंग करने के लिए स्विच कर रहा हूं।
IfTrue

1
टाइप स्क्रिप्ट में यह कैसे करें?
ATHER

मेरे लिए सबसे अच्छा जवाब !! जावास्क्रिप्ट में संदर्भ के अनुसार इलाज की गई वस्तुओं का सबसे अच्छा उदाहरण
विकास गौतम

4

एक संभावित समाधान एक init फ़ंक्शन का उपयोग करके पेरेंट कंट्रोलर में चाइल्ड कंट्रोलर को इंजेक्ट करना है।

संभावित कार्यान्वयन:

<div ng-controller="ParentController as parentCtrl">
   ...

    <div ng-controller="ChildController as childCtrl" 
         ng-init="ChildCtrl.init()">
       ...
    </div>
</div>

ChildControllerआपके पास कहां है:

app.controller('ChildController',
    ['$scope', '$rootScope', function ($scope, $rootScope) {
    this.init = function() {
         $scope.parentCtrl.childCtrl = $scope.childCtrl;
         $scope.childCtrl.test = 'aaaa';
    };

}])

तो अब ParentControllerआप में उपयोग कर सकते हैं:

app.controller('ParentController',
    ['$scope', '$rootScope', 'service', function ($scope, $rootScope, service) {

    this.save = function() {
        service.save({
            a:  $scope.parentCtrl.ChildCtrl.test
        });
     };

}])

महत्वपूर्ण:
ठीक से काम करने के लिए आपको निर्देश का उपयोग करना होगा ng-controllerऔर प्रत्येक नियंत्रक का नाम बदलना होगा asजैसे कि मैंने html जैसे में किया था।

टिप्स: प्रक्रिया के दौरान
क्रोम प्लगइन एनजी-इंस्पेक्टर का उपयोग करें । यह आपको पेड़ को समझने में मदद करने वाला है।


3

$ Emit और $ प्रसारण का उपयोग करना , (जैसा कि ऊपर टिप्पणी में walv द्वारा उल्लेख किया गया है)

किसी घटना को ऊपर की ओर करने के लिए (बच्चे से माता-पिता तक)

$scope.$emit('myTestEvent', 'Data to send');

किसी घटना को नीचे की ओर (माता-पिता से बच्चे तक) आग देना

$scope.$broadcast('myTestEvent', {
  someProp: 'Sending you some data'
});

और अंत में सुनने के लिए

$scope.$on('myTestEvent', function (event, data) {
  console.log(data);
});

अधिक जानकारी के लिए: - https://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/

का आनंद लें :)


1

हां, हम चाइल्ड कंट्रोलर से वेरिएबल को पैरेंट कंट्रोलर में वेरिएबल में असाइन कर सकते हैं। यह एक संभव तरीका है:

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

स्पष्टीकरण: दो नियंत्रक हैं। Html में, ध्यान दें कि अभिभावक नियंत्रक बच्चे के नियंत्रक को घेरता है। इसका मतलब है कि चाइल्ड कंट्रोलर से पहले पेरेंट कंट्रोलर को एग्जीक्यूट किया जाएगा। तो, पहले setValue () को परिभाषित किया जाएगा और फिर कंट्रोल चाइल्ड कंट्रोलर के पास जाएगा। $ स्कोप.भारती को "बच्चे" के रूप में सौंपा जाएगा। फिर इस चाइल्ड स्कोप को पैरेंट कंट्रोलर के फंक्शन के लिए एक तर्क के रूप में पारित किया जाएगा, जहाँ $ स्कोप.साइन को "बच्चे" के रूप में मान मिलेगा।

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script type="text/javascript">
    var app = angular.module('myApp',[]);

    app.controller('child',function($scope){
        $scope.variable = "child";
        $scope.$parent.setValue($scope);
    });

    app.controller('parent',function($scope){
        $scope.setValue = function(childscope) {
            $scope.assign = childscope.variable;
        }
    });

</script>
<body ng-app="myApp">
 <div ng-controller="parent">
    <p>this is parent: {{assign}}</p>
    <div ng-controller="child">
        <p>this is {{variable}}</p>
    </div>
 </div>
</body>
</html>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.