angularJS: पैरेंट स्कोप में चाइल्ड स्कोप फंक्शन को कैसे कॉल करें


95

चाइल्ड स्कोप में परिभाषित विधि को उसके मूल स्कोप से कैसे कह सकते हैं?

function ParentCntl() {
    // I want to call the $scope.get here
}

function ChildCntl($scope) {
    $scope.get = function() {
        return "LOL";    
    }
}

http://jsfiddle.net/wUPdW/


2
सर्वश्रेष्ठ शर्त, एक सेवा को परिभाषित करें, उस सेवा को दोनों नियंत्रकों में इंजेक्ट करें। या rootcope का उपयोग करें।
tymeJV

जवाबों:


145

आप $broadcastमाता-पिता से एक बच्चे के लिए उपयोग कर सकते हैं :

function ParentCntl($scope) {

    $scope.msg = "";
    $scope.get = function(){
        $scope.$broadcast ('someEvent');
        return  $scope.msg;        
    }
}

function ChildCntl($scope) {               
    $scope.$on('someEvent', function(e) {  
        $scope.$parent.msg = $scope.get();            
    });

    $scope.get = function(){
        return "LOL";    
    }
}

वर्किंग फिडल: http://jsfiddle.net/wUPdW/2/

अद्यतन : एक और संस्करण है, कम युग्मित और अधिक परीक्षण योग्य:

function ParentCntl($scope) {
    $scope.msg = "";
    $scope.get = function(){
        $scope.$broadcast ('someEvent');
        return  $scope.msg;        
    }

    $scope.$on('pingBack', function(e,data) {  
        $scope.msg = data;        
    });
}

function ChildCntl($scope) {               
    $scope.$on('someEvent', function(e) {  
        $scope.$emit("pingBack", $scope.get());        
    });

    $scope.get = function(){
        return "LOL";    
    }
}

फिडल: http://jsfiddle.net/uypo360u/


यह बहुत मजेदार है! लेकिन, क्या होगा यदि आप नहीं चाहते (जानना चाहते हैं) कॉलर स्कोप कहाँ है (मेरा मतलब है कि इन $scope.$parentया इन $scope.$parent.$parentआदि)? आह, हाँ: परमेस में एक कॉलबैक पास! :)
user2173353

@ user2173353 आप बहुत सही हैं; एक और तरीका है: $emitबच्चे से लेकर माता-पिता तक। मुझे लगता है कि यह मेरे उत्तर को अद्यतन करने का समय है ..
चेर्निव

क्या वैश्विक श्रोता को कॉल करना अच्छा है, जहां इस मामले में कहीं भी बाल नियंत्रक है? यह एंटीपैटर्न नहीं है और बाद में परीक्षण करना कठिन है? क्या हमें इंजेक्शन या स्मथ का उपयोग नहीं करना चाहिए?
कैलम्बर्ड

@calmbird, प्रत्येक चीज़ का सावधानीपूर्वक उपयोग किया जाना चाहिए, यह सुनिश्चित करने के लिए है .. कुछ इसी तरह के मामलों में सेवाओं का उपयोग करना पसंद करते हैं। वैसे भी, मैंने अधिक सुरुचिपूर्ण संस्करण (बिना कष्टप्रद $parent) जोड़ा
चेर्निव

9
यह दृष्टिकोण क्लीनर है। कॉलबैक पास करें $broadcastऔर आप pingBackपूरी तरह से समाप्त कर सकते हैं।
poshest

34

मुझे एक और उपाय सुझाने दें:

var app = angular.module("myNoteApp", []);


app.controller("ParentCntl", function($scope) {
    $scope.obj = {};
});

app.controller("ChildCntl", function($scope) {
    $scope.obj.get = function() {
            return "LOL";    
    };
});

कम कोड और प्रोटोटाइप विरासत का उपयोग कर।

खनखनाहट


क्या कोई समझा सकता है कि क्या यह दृष्टिकोण ऊपर बताए गए घटना संचालित दृष्टिकोण से बेहतर है जो कि मामलों में है और यदि यह है, तो क्यों? क्या होगा यदि आपके पास बहु lvl पदानुक्रम w बाल नियंत्रक है? यह काम करेगा अगर obj.get एक बाल नियंत्रक के अंदर एक बाल नियंत्रक के रूप में परिभाषित किया गया है जब तक कि नियंत्रकों में से कोई भी एक ही फ़ंक्शन को परिभाषित नहीं करता है? पहले ही, आपका बहुत धन्यवाद।
ZvKa

1
मैंने जो कहा, उसे सही किया जो पूरी तरह से सच नहीं है। आपने जो कहा उसमें आप सही हैं: गुंजाइश वंशानुक्रम केवल एक ही दिशा में लागू होता है .... बच्चे -> माता-पिता। वास्तव में यहां क्या हो रहा है कि यदि आप $ गुंजाइश को परिभाषित करते हैं। बच्चे के दायरे में भूल जाओ, 'get' को केवल बाल दायरे (कभी-कभी आदिम परिभाषा के रूप में संदर्भित) पर परिभाषित किया जाएगा। लेकिन जब आप $ गुंजाइश.obj.get को परिभाषित करते हैं, तो चाइल्ड स्कोप obj की तलाश करेगा जो कि पेरेंट स्कोप पर परिभाषित किया गया है, जो पदानुक्रम है।
कैंटचिट

3
अगर बच्चे का अपना अलग दायरा होगा तो यह कैसे काम करेगा?
दिनेश

2
प्रश्न अलग-थलग दायरे की बात नहीं कर रहा था, हालाँकि यदि आपके पास अलग-अलग गुंजाइश है तो आप अलग-अलग स्कोप बाइंडिंग का उपयोग कर सकते हैं। इमो, ब्रॉडकास्टिंग थोड़ा गड़बड़ है।
Canttouchit

2
मुझे नहीं लगता कि यह उदाहरण संभव है यदि आपको पेरेंट के कंट्रोलर से चाइल्ड कंट्रोलर के फंक्शन को एक्सेस करने की जरूरत है , न कि टेम्पलेट की। यह उदाहरण केवल टेम्प्लेट पर दो-तरफ़ा बाइंडिंग के कारण काम करता है, जो मुझे लगता है $scope.obj.get()कि एक मान्य फ़ंक्शन होने तक मतदान होता रहता है।
डेनिम

11

बच्चे के शुरुआती होने पर माता-पिता पर बच्चे के कार्य को पंजीकृत करें। मैंने टेम्पलेट में स्पष्टता के लिए "के रूप में" संकेतन का उपयोग किया।

खाका

<div ng-controller="ParentCntl as p">
  <div ng-controller="ChildCntl as c" ng-init="p.init(c.get)"></div>
</div>

नियंत्रकों

...
function ParentCntl() {
  var p = this;
  p.init = function(fnToRegister) {
    p.childGet = fnToRegister;
  };
 // call p.childGet when you want
}

function ChildCntl() {
  var c = this;
  c.get = function() {
    return "LOL";    
  };
}

"लेकिन", आप कहते हैं, " ng-init इस तरह से इस्तेमाल नहीं किया जाना चाहिए !"। खैर, हां, लेकिन

  1. यह प्रलेखन स्पष्ट नहीं करता है कि क्यों नहीं, और
  2. मेरा मानना ​​है कि प्रलेखन लेखकों ने इसके लिए सभी संभव उपयोग मामलों पर विचार किया।

मैं कहता हूं कि यह इसके लिए एक अच्छा उपयोग है। यदि आप मुझे नीचा दिखाना चाहते हैं, तो कृपया कारणों के साथ टिप्पणी करें! :)

मुझे यह दृष्टिकोण पसंद है क्योंकि यह घटकों को अधिक मॉड्यूलर रखता है। केवल बाइंडिंग टेम्पलेट में हैं, और इसका मतलब है कि

  • चाइल्ड कंट्रोलर को अपने फंक्शन को जोड़ने के लिए किस वस्तु के बारे में कुछ नहीं जानना है (जैसे @ कैंटचौइट के उत्तर में)
  • माता-पिता के नियंत्रण का उपयोग किसी भी अन्य बच्चे के नियंत्रण के साथ किया जा सकता है, जिसके पास एक फ़ंक्शन है
  • प्रसारण की आवश्यकता नहीं है, जो एक बड़े ऐप में बहुत बदसूरत हो जाएगा जब तक आप घटना के नाम स्थान को कसकर नियंत्रित नहीं करते हैं

यह दृष्टिकोण अधिक बारीकी से टेरो के विचारों को निर्देश के साथ संशोधित करने का विचार करता है (ध्यान दें कि उनके मॉड्यूलर उदाहरण में, contestantsमाता-पिता से "बच्चे" निर्देश पर पारित हो गया है)।

वास्तव में एक अन्य समाधान ChildCntlएक निर्देश के रूप में लागू करने पर विचार करना और विधि &को पंजीकृत करने के लिए बाध्यकारी का उपयोग करना हो सकता है init


1
मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन यह एक बुरे विचार की तरह लगता है क्योंकि माता-पिता बच्चे को नष्ट करने के बाद बच्चे को एक संदर्भ रख सकते हैं।
एमी ब्लेंकशिप

यह ब्रॉडकास्टिंग इवेंट्स की तुलना में कहीं ज्यादा क्लिनर सॉल्यूशन है। न सही, बल्कि बेहतर। हालांकि सफाई वास्तव में एक मुद्दा है।
एमसीवी

-1

आप बच्चे को वस्तु बना सकते हैं।

var app = angular.module("myApp", []);


app.controller("ParentCntl", function($scope) {
    $scope.child= {};
    $scope.get = function(){
      return $scope.child.get(); // you can call it. it will return 'LOL'
    }
   // or  you can call it directly like $scope.child.get() once it loaded.
});

app.controller("ChildCntl", function($scope) {
    $scope.obj.get = function() {
            return "LOL";    
    };
});

यहां बच्चा पाने का तरीका साबित हो रहा है।

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