AngularJS में नियंत्रकों के बीच संवाद करने का सही तरीका क्या है?


473

नियंत्रकों के बीच संवाद करने का सही तरीका क्या है?

मैं वर्तमान में एक भयानक ठग का उपयोग कर रहा हूँ window:

function StockSubgroupCtrl($scope, $http) {
    $scope.subgroups = [];
    $scope.handleSubgroupsLoaded = function(data, status) {
        $scope.subgroups = data;
    }
    $scope.fetch = function(prod_grp) {
        $http.get('/api/stock/groups/' + prod_grp + '/subgroups/').success($scope.handleSubgroupsLoaded);
    }
    window.fetchStockSubgroups = $scope.fetch;
}

function StockGroupCtrl($scope, $http) {
    ...
    $scope.select = function(prod_grp) {
        $scope.selectedGroup = prod_grp;
        window.fetchStockSubgroups(prod_grp);
    }
}

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

1
इस मुद्दे के संबंध में कृपया नीचे दिए गए उत्तर में टिप्पणी देखें। $ प्रसारण अब $ emit से अधिक महंगा नहीं है। मेरे द्वारा संदर्भित jsperf लिंक देखें।
zumalifeguard

जवाबों:


457

संपादित करें : इस उत्तर में संबोधित मुद्दे को angular.js संस्करण 1.2.7 में हल किया गया है । $broadcastअब अपंजीकृत स्कोप पर बुदबुदाहट से बचा जाता है और $ उतनी ही तेजी से चलता है। $ प्रसारण प्रदर्शन कोणीय 1.2.16 के साथ $ emit के समान हैं

तो, अब आप कर सकते हैं:

  • से उपयोग $broadcastकरें$rootScope
  • घटना के बारे में जानने के $on लिए स्थानीय से$scope उपयोग करके सुनें

मूल उत्तर नीचे

मैं अत्यधिक सलाह देता हूं कि $rootScope.$broadcast+ का उपयोग न करें $scope.$onबल्कि $rootScope.$emit+ $rootScope.$on। पूर्व में गंभीर प्रदर्शन समस्याओं का कारण हो सकता है जैसा कि @numan द्वारा उठाया गया है। ऐसा इसलिए है क्योंकि घटना सभी scopes के माध्यम से नीचे बुलबुला जाएगा ।

हालांकि, बाद के (का उपयोग कर $rootScope.$emit+ $rootScope.$on) करता नहीं इस से ग्रस्त है और इसलिए एक तेजी से संचार चैनल के रूप में इस्तेमाल किया जा सकता!

के कोणीय प्रलेखन से $emit:

एक घटना के नाम को ऊपर की ओर गुंजाइश के माध्यम से प्रेषित करता है जो पदानुक्रम पंजीकृत को सूचित करता है

चूंकि ऊपर कोई गुंजाइश नहीं है $rootScope, इसलिए कोई हलचल नहीं हो रही है। यह उपयोग करने के लिए पूरी तरह से सुरक्षित है $rootScope.$emit()/ $rootScope.$on()एक EventBus के रूप में।

हालांकि, नियंत्रक के भीतर से इसका उपयोग करते समय एक गोचा है। यदि आप सीधे $rootScope.$on()किसी कंट्रोलर से बंधते हैं, तो आपको अपने स्थानीय $scopeको नष्ट होने पर बंधन को स्वयं साफ करना होगा । इसका कारण यह है कि नियंत्रकों (सेवाओं के विपरीत) एक आवेदन के जीवनकाल में कई बार त्वरित रूप से प्राप्त कर सकते हैं, जिसके परिणामस्वरूप अंत में सभी जगह स्मृति लीक बनाने के लिए बाध्य होने का योग होगा :)

अपंजीकृत लिए, बस अपने पर सुनने $scopeकी $destroyऔर घटना तो समारोह है कि द्वारा दिया गया था कहते हैं $rootScope.$on

angular
    .module('MyApp')
    .controller('MyController', ['$scope', '$rootScope', function MyController($scope, $rootScope) {

            var unbind = $rootScope.$on('someComponent.someCrazyEvent', function(){
                console.log('foo');
            });

            $scope.$on('$destroy', unbind);
        }
    ]);

मैं कहूंगा, यह वास्तव में एक कोणीय विशिष्ट बात नहीं है क्योंकि यह अन्य EventBus कार्यान्वयनों पर भी लागू होता है, आपको संसाधनों को साफ करना होगा।

हालाँकि, आप उन मामलों के लिए अपना जीवन आसान बना सकते हैं। उदाहरण के लिए, आप बंदर को पैच कर सकते हैं $rootScopeऔर उसे दे सकते हैं, जो स्थानीय पर नष्ट हो जाने $onRootScopeपर $rootScopeसीधे हैंडलर को साफ करता है $scope

इस $rootScopeतरह की $onRootScopeविधि प्रदान करने के लिए बंदर पैच को साफ करने का सबसे अच्छा तरीका एक डेकोरेटर के माध्यम से होगा (एक रन ब्लॉक शायद इसे ठीक भी करेगा लेकिन psstst, किसी को भी न बताएं)

यह सुनिश्चित करने के लिए कि $onRootScopeजब $scopeहम उपयोग करते हैं Object.defineProperty()और सेट करते हैं , तो संपत्ति अप्रत्याशित नहीं दिखाई देती enumerableहै false। ध्यान रखें कि आपको ES5 शिम की आवश्यकता हो सकती है।

angular
    .module('MyApp')
    .config(['$provide', function($provide){
        $provide.decorator('$rootScope', ['$delegate', function($delegate){

            Object.defineProperty($delegate.constructor.prototype, '$onRootScope', {
                value: function(name, listener){
                    var unsubscribe = $delegate.$on(name, listener);
                    this.$on('$destroy', unsubscribe);

                    return unsubscribe;
                },
                enumerable: false
            });


            return $delegate;
        }]);
    }]);

इस विधि के साथ ऊपर से कंट्रोलर कोड को सरल बनाया जा सकता है:

angular
    .module('MyApp')
    .controller('MyController', ['$scope', function MyController($scope) {

            $scope.$onRootScope('someComponent.someCrazyEvent', function(){
                console.log('foo');
            });
        }
    ]);

तो इस सब के अंतिम परिणाम के रूप में मैं आपको $rootScope.$emit+ का उपयोग करने की अत्यधिक सलाह देता हूं $scope.$onRootScope

Btw, मैं कोणीय कोर के भीतर समस्या को संबोधित करने के लिए कोणीय टीम को समझाने की कोशिश कर रहा हूं। यहाँ एक चर्चा चल रही है: https://github.com/angular/angular.js/issues/4574

यहाँ एक jsperf है जो दिखाता है कि एक बढ़िया प्रभाव $broadcastमात्र 100 के साथ एक परिपूर्ण परिदृश्य में तालिका में लाता है $scope

http://jsperf.com/rootscope-emit-vs-rootscope-broadcast

jsperf परिणाम


मैं आपका दूसरा विकल्प करने की कोशिश कर रहा हूं, लेकिन मुझे एक त्रुटि मिल रही है: अनकैप्ड टाइपर्रर: संपत्ति को फिर से परिभाषित नहीं कर सकता: $ onRootScope वहीं जहां मैं Object.defineProperty कर रहा हूं ....
स्कॉट

हो सकता है कि जब मैंने इसे यहां चिपकाया हो तो मैंने कुछ खराब कर दिया हो। मैं इसका उत्पादन में उपयोग करता हूं और यह बहुत अच्छा काम करता है। मैं कल देखूंगा :)
क्रिस्टोफ

@ देखें कि मैंने इसे चिपकाया था लेकिन पहले से ही कोड सही था और ठीक वैसा ही है जैसा हम उत्पादन में इस्तेमाल करते हैं। क्या आप दोहरा सकते हैं, कि आपकी साइट पर टाइपो नहीं है? समस्या निवारण में सहायता के लिए क्या मैं आपका कोड देख सकता हूँ?
क्रिस्टोफ

@Christoph IE8 में डेकोरेटर करने का एक अच्छा तरीका है, क्योंकि यह नॉन-डोम ऑब्जेक्ट्स पर Object.defineProperty का समर्थन नहीं करता है?
joshschreuder

59
यह समस्या का एक बहुत ही चतुर समाधान था, लेकिन इसकी अब आवश्यकता नहीं है। एंगुलर का नवीनतम संस्करण (1.2.16), और शायद पहले, इस समस्या को ठीक किया गया है। अब $ प्रसारण बिना कारण के प्रत्येक वंश नियंत्रक पर नहीं जाएगा। यह केवल उन लोगों का दौरा करेगा जो वास्तव में घटना के लिए सुन रहे हैं। मैंने ऊपर बताए गए jsperf को यह प्रदर्शित करने के लिए अद्यतन किया कि समस्या अब ठीक हो गई है: jsperf.com/rootscope-emit-vs-rootscope-broadcast/27
zumalifeguard

107

यहाँ शीर्ष उत्तर एक कोणीय समस्या के आसपास का काम था जो अब मौजूद नहीं है (कम से कम संस्करणों में> 1.2.16 और "शायद पहले") जैसा कि @zumalifeguard ने उल्लेख किया है। लेकिन मैंने वास्तविक समाधान के बिना इन सभी उत्तरों को पढ़ना छोड़ दिया है।

यह मुझे लगता है कि जवाब अब होना चाहिए

  • से उपयोग $broadcastकरें$rootScope
  • घटना के बारे में जानने के $on लिए स्थानीय से$scope उपयोग करके सुनें

तो प्रकाशित करने के लिए

// EXAMPLE PUBLISHER
angular.module('test').controller('CtrlPublish', ['$rootScope', '$scope',
function ($rootScope, $scope) {

  $rootScope.$broadcast('topic', 'message');

}]);

और सब्सक्राइब करे

// EXAMPLE SUBSCRIBER
angular.module('test').controller('ctrlSubscribe', ['$scope',
function ($scope) {

  $scope.$on('topic', function (event, arg) { 
    $scope.receiver = 'got your ' + arg;
  });

}]);

Plunkers

आप स्थानीय पर श्रोता पंजीकृत करते हैं $scope, यह हो जाएगा द्वारा स्वचालित रूप से नष्ट कर दिया $destroyही जब जुड़े नियंत्रक निकाल दिया जाता है।


1
क्या आपको पता है कि इसी पैटर्न को controllerAsसिंटैक्स के साथ इस्तेमाल किया जा सकता है ? मैं $rootScopeइस घटना को सुनने के लिए सब्सक्राइबर में उपयोग करने में सक्षम था , लेकिन अगर कोई अलग पैटर्न था तो मैं बस उत्सुक था।
14

3
@ हेडेज मुझे लगता है कि आप $scopeस्पष्ट रूप से इंजेक्शन लगा सकते हैं । जॉन पापा$scope अपने नियंत्रकों के "आउट" रखने के अपने सामान्य नियम में एक "अपवाद" होने के बारे में लिखते हैं (मैं उद्धरण का उपयोग करता हूं क्योंकि जैसा कि वह Controller Asअभी भी उल्लेख करता है $scope, यह सिर्फ बोनट के नीचे है)।
poshest

बोनट के नीचे का मतलब है कि आप इंजेक्शन के माध्यम से इसे प्राप्त कर सकते हैं?
edhedges

2
@edhedges मैंने controller asअनुरोध के रूप में एक सिंटैक्स विकल्प के साथ अपना जवाब अपडेट किया। मुझे आशा है कि आपका यही मतलब है।
पॉशेस्ट

3
@dsdsdsd, सेवाएं / कारखाने / प्रदाता हमेशा के लिए आसपास रहेंगे। एक कोणीय ऐप में हमेशा उनमें से केवल एक (एकल) होता है। दूसरी ओर नियंत्रकों को कार्यक्षमता से जोड़ा जाता है: घटक / निर्देश / एनजी-नियंत्रक, जिन्हें दोहराया जा सकता है (जैसे कि एक वर्ग से बनी वस्तुएं) और वे आते हैं और आवश्यकतानुसार चलते हैं। जब आपको इसकी आवश्यकता नहीं है, तो आप एक नियंत्रण और इसके नियंत्रक को क्यों रखना चाहते हैं? यह एक स्मृति रिसाव की बहुत परिभाषा है।
poshest

54

$ RootScope का उपयोग करना PubSub संचार के लिए $ प्रसारण और $ गुंजाइश। $।

इसके अलावा, इस पोस्ट को देखें: AngularJS - नियंत्रकों के बीच संवाद


3
यही कारण है कि वीडियो बस नयापन $rootScopeऔर $watch। यकीन नहीं होता कि कोई सुधार है।
nilskp

42

चूँकि डिफाइनप्रॉपर्टी में ब्राउज़र कम्पैटिबिलिटी समस्या है, मुझे लगता है कि हम किसी सेवा का उपयोग करने के बारे में सोच सकते हैं।

angular.module('myservice', [], function($provide) {
    $provide.factory('msgBus', ['$rootScope', function($rootScope) {
        var msgBus = {};
        msgBus.emitMsg = function(msg) {
        $rootScope.$emit(msg);
        };
        msgBus.onMsg = function(msg, scope, func) {
            var unbind = $rootScope.$on(msg, func);
            scope.$on('$destroy', unbind);
        };
        return msgBus;
    }]);
});

और इसे इस तरह नियंत्रक में उपयोग करें:

  • नियंत्रक १

    function($scope, msgBus) {
        $scope.sendmsg = function() {
            msgBus.emitMsg('somemsg')
        }
    }
  • नियंत्रक २

    function($scope, msgBus) {
        msgBus.onMsg('somemsg', $scope, function() {
            // your logic
        });
    }

7
स्वत: सदस्यता समाप्त करने के लिए +1 जब स्कोप नष्ट हो जाता है।
फेडरिको नफ़रिया

6
मुझे यह समाधान पसंद है। मेरे द्वारा किए गए 2 परिवर्तन: (1) उपयोगकर्ता को उत्सर्जित संदेश के लिए 'डेटा' में पारित करने की अनुमति देता है (2) पासिंग को 'स्कोप' को वैकल्पिक बनाता है ताकि इसे सिंगलटन सेवाओं के साथ-साथ नियंत्रकों में भी इस्तेमाल किया जा सके। आप उन परिवर्तनों को यहां लागू कर सकते हैं: gist.github.com/turtlemonvh/10686980/…
turtlemonvh


15

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

मैं एक सेवा का उपयोग करने का सुझाव दूंगा। यहाँ मैंने हाल ही में इसे अपनी एक परियोजना में कैसे लागू किया है - https://gist.github.com/3384419

मूल विचार - सेवा के रूप में पबसुब / इवेंट बस को पंजीकृत करें। फिर उस इवेंटबस को इंजेक्ट करें जहाँ आपको कभी भी इवेंट्स / टॉपिक्स को सब्सक्राइब या पब्लिश करने की जरूरत है।


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

1
एक उचित बिंदु है। मुझे लगता है कि यह आपके आवेदन को कैसे आर्किटेक्ट द्वारा हल किया जा सकता है। मेरे मामले में, मेरे पास एक एकल पृष्ठ ऐप है, इसलिए यह एक और अधिक समस्या है। कहा जा रहा है कि, मुझे लगता है कि यह बहुत साफ होगा यदि कोणीय में जीवन चक्र के हुक होते हैं जहां आप इस तरह से चीजों को तार / खोल सकते हैं।
अंकन सलाति

6
मैं इसे यहीं छोड़ता हूं क्योंकि पहले किसी ने नहीं कहा था। एक EventBus रूप rootScope का उपयोग करना है नहीं अक्षम $rootScope.$emit()केवल ऊपर की तरफ बुलबुले। हालाँकि, चूंकि इसमें कोई गुंजाइश नहीं है, $rootScopeइसलिए डरने की कोई बात नहीं है। तो अगर आप अभी उपयोग कर रहे हैं $rootScope.$emit()और $rootScope.$on()आपके पास एक तेज़ सिस्टम वाइड इवेंटबस होगा।
क्रिस्टोफ

1
केवल एक चीज जिसकी आपको जानकारी होनी चाहिए, यदि आप $rootScope.$on()अपने कंट्रोलर के अंदर उपयोग करते हैं, तो आपको इवेंट बाइंडिंग को साफ करने की आवश्यकता होगी, अन्यथा वे योग करेंगे क्योंकि यह एक नया हर बार बना रहा है जब कंट्रोलर त्वरित है और वे नहीं करते हैं आप के लिए स्वचालित रूप से नष्ट कर रहे हैं जब से आप $rootScopeसीधे करने के लिए बाध्य कर रहे हैं।
क्रिस्टोफ

एंगुलर का नवीनतम संस्करण (1.2.16), और शायद पहले, इस समस्या को ठीक किया गया है। अब $ प्रसारण बिना कारण के प्रत्येक वंश नियंत्रक पर नहीं जाएगा। यह केवल उन लोगों का दौरा करेगा जो वास्तव में घटना के लिए सुन रहे हैं। मैंने ऊपर बताए गए jsperf को प्रदर्शित किया कि यह प्रदर्शित करने के लिए कि अब समस्या ठीक हो गई है: jsperf.com/rootscope-emit-vs-rootscope-broadcast/27
zumalifeguard

14

किसी सेवा के भीतर प्राप्त करें और निर्धारित विधियों का उपयोग करके आप नियंत्रकों के बीच संदेश बहुत आसानी से पारित कर सकते हैं।

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

myApp.factory('myFactoryService',function(){


    var data="";

    return{
        setData:function(str){
            data = str;
        },

        getData:function(){
            return data;
        }
    }


})


myApp.controller('FirstController',function($scope,myFactoryService){
    myFactoryService.setData("Im am set in first controller");
});



myApp.controller('SecondController',function($scope,myFactoryService){
    $scope.rslt = myFactoryService.getData();
});

HTML HTML में आप इस तरह से चेक कर सकते हैं

<div ng-controller='FirstController'>  
</div>

<div ng-controller='SecondController'>
    {{rslt}}
</div>

+1 उन स्पष्ट-एक बार-आप-बताए गए तरीकों में से एक है - उत्कृष्ट! मैंने सेट (कुंजी, मूल्य) और प्राप्त (कुंजी) विधियों के साथ एक अधिक सामान्य संस्करण लागू किया है - $ प्रसारण के लिए एक उपयोगी विकल्प।
टोनीविल्क

8

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

  • नियंत्रकों में साझा स्टेटलेस या स्टेटफुल कोड चलाने के लिए - इसके बजाय कोणीय सेवाओं का उपयोग करें।
  • अन्य घटकों के जीवन-चक्र को तत्काल या प्रबंधित करने के लिए (उदाहरण के लिए, सेवा उदाहरण बनाने के लिए)।

Ref: कोणीय डॉक्स यहां लिंक करें


5

मैंने वास्तव में नियंत्रकों के बीच एक संदेश बस के रूप में पोस्टल.जेएस का उपयोग करना शुरू कर दिया है।

संदेश बस के रूप में इसके बहुत सारे लाभ हैं जैसे कि AMQP स्टाइल बाइंडिंग, जिस तरह से डाक w / iFrames और वेब सॉकेट, और कई और चीजें एकीकृत कर सकता है।

मैं एक डेकोरेटर का उपयोग करने के लिए पोस्टल सेट अप $scope.$bus...

angular.module('MyApp')  
.config(function ($provide) {
    $provide.decorator('$rootScope', ['$delegate', function ($delegate) {
        Object.defineProperty($delegate.constructor.prototype, '$bus', {
            get: function() {
                var self = this;

                return {
                    subscribe: function() {
                        var sub = postal.subscribe.apply(postal, arguments);

                        self.$on('$destroy',
                        function() {
                            sub.unsubscribe();
                        });
                    },
                    channel: postal.channel,
                    publish: postal.publish
                };
            },
            enumerable: false
        });

        return $delegate;
    }]);
});

यहाँ विषय पर एक ब्लॉग पोस्ट के लिए एक लिंक है ...
http://jonathancreamer.com/an-angular-event-bus-with-postal-js/


3

यह मैं कारखाने / सेवाओं और सरल निर्भरता इंजेक्शन (DI) के साथ कैसे करता हूं ।

myApp = angular.module('myApp', [])

# PeopleService holds the "data".
angular.module('myApp').factory 'PeopleService', ()->
  [
    {name: "Jack"}
  ]

# Controller where PeopleService is injected
angular.module('myApp').controller 'PersonFormCtrl', ['$scope','PeopleService', ($scope, PeopleService)->
  $scope.people = PeopleService
  $scope.person = {} 

  $scope.add = (person)->
    # Simply push some data to service
    PeopleService.push angular.copy(person)
]

# ... and again consume it in another controller somewhere...
angular.module('myApp').controller 'PeopleListCtrl', ['$scope','PeopleService', ($scope, PeopleService)->
  $scope.people = PeopleService
]

1
आपके दो नियंत्रक संवाद नहीं करते हैं, वे केवल एक ही सेवा का उपयोग करते हैं। यह वही बात नहीं है।
ग्रेग

@ आप एक साझा सेवा होने और जहां आवश्यकता हो, $ घड़ियाँ जोड़कर कम कोड के साथ एक ही चीज़ प्राप्त कर सकते हैं।
कापज

3

मुझे यह पसंद आया कि किस तरह $rootscope.emitसे अंतर-संचार को प्राप्त करने के लिए उपयोग किया जाता है। मैं वैश्विक अंतरिक्ष को प्रदूषित किए बिना स्वच्छ और प्रदर्शन प्रभावी समाधान का सुझाव देता हूं।

module.factory("eventBus",function (){
    var obj = {};
    obj.handlers = {};
    obj.registerEvent = function (eventName,handler){
        if(typeof this.handlers[eventName] == 'undefined'){
        this.handlers[eventName] = [];  
    }       
    this.handlers[eventName].push(handler);
    }
    obj.fireEvent = function (eventName,objData){
       if(this.handlers[eventName]){
           for(var i=0;i<this.handlers[eventName].length;i++){
                this.handlers[eventName][i](objData);
           }

       }
    }
    return obj;
})

//Usage:

//In controller 1 write:
eventBus.registerEvent('fakeEvent',handler)
function handler(data){
      alert(data);
}

//In controller 2 write:
eventBus.fireEvent('fakeEvent','fakeData');

मेमोरी लीक के लिए आपको इवेंट श्रोताओं से डी-रजिस्टर करने के लिए एक अतिरिक्त तरीका जोड़ना चाहिए। वैसे भी अच्छा तुच्छ नमूना
रफ्फू

2

यहाँ त्वरित और गंदा तरीका है।

// Add $injector as a parameter for your controller

function myAngularController($scope,$injector){

    $scope.sendorders = function(){

       // now you can use $injector to get the 
       // handle of $rootScope and broadcast to all

       $injector.get('$rootScope').$broadcast('sinkallships');

    };

}

यहां किसी भी भाई को नियंत्रित करने के लिए एक उदाहरण समारोह है:

$scope.$on('sinkallships', function() {

    alert('Sink that ship!');                       

});

और निश्चित रूप से यहां आपका HTML है:

<button ngclick="sendorders()">Sink Enemy Ships</button>

16
आप सिर्फ इंजेक्शन क्यों नहीं लगाते $rootScope?
पीटर हेरोलेन को

1

कोणीय 1.5 शुरू करना और यह घटक आधारित विकास फोकस है। बातचीत करने के लिए घटकों के लिए अनुशंसित तरीका 'आवश्यकता' संपत्ति के उपयोग और संपत्ति बाइंडिंग (इनपुट / आउटपुट) के माध्यम से है।

एक घटक को दूसरे घटक की आवश्यकता होगी (उदाहरण के लिए मूल घटक) और इसे नियंत्रक का संदर्भ मिलता है:

angular.module('app').component('book', {
    bindings: {},
    require: {api: '^app'},
    template: 'Product page of the book: ES6 - The Essentials',
    controller: controller
});

फिर आप अपने चाइल्ड कंपोनेंट में रूट कंपोनेंट के तरीकों का उपयोग कर सकते हैं:

$ctrl.api.addWatchedBook('ES6 - The Essentials');

यह रूट कंपोनेंट कंट्रोलर फंक्शन है:

function addWatchedBook(bookName){

  booksWatched.push(bookName);

}

यहाँ एक पूर्ण वास्तु अवलोकन है: घटक संचार


0

आप मॉड्यूल में कहीं भी इस हैलो फ़ंक्शन का उपयोग कर सकते हैं

नियंत्रक एक

 $scope.save = function() {
    $scope.hello();
  }

दूसरा नियंत्रक

  $rootScope.hello = function() {
    console.log('hello');
  }

अधिक जानकारी यहाँ


7
पार्टी के लिए थोड़ा देर से लेकिन: ऐसा मत करो। फंक्शन को रूट स्कोप पर रखना एक फंक्शन को ग्लोबल बनाने के समान है, जिससे सभी तरह की समस्याएं हो सकती हैं।
दान पेंट्री

0

मैं एक सेवा बनाऊंगा और अधिसूचना का उपयोग करूंगा।

  1. अधिसूचना सेवा में एक विधि बनाएँ
  2. अधिसूचना सेवा में अधिसूचना प्रसारित करने के लिए एक सामान्य विधि बनाएँ।
  3. सोर्स कंट्रोलर से notificationService.Method पर कॉल करें। जरूरत पड़ने पर मैं भी इसी वस्तु को जारी रखता हूं।
  4. इस पद्धति के भीतर, मैं सूचना सेवा में डेटा जारी रखता हूं और सामान्य सूचना विधि कहता हूं।
  5. गंतव्य नियंत्रक में मैं प्रसारण कार्यक्रम के लिए सुनता ($ गुंजाइश.न) और अधिसूचना सेवा से डेटा एक्सेस करता हूं।

किसी भी बिंदु पर अधिसूचना सेवा एकल है क्योंकि यह संपूर्ण डेटा प्रदान करने में सक्षम होना चाहिए।

उम्मीद है की यह मदद करेगा


0

आप AngularJS बिल्ड-इन सेवा का उपयोग कर सकते हैं $rootScope और अपने दोनों नियंत्रकों में इस सेवा को इंजेक्ट । फिर आप उन घटनाओं के लिए सुन सकते हैं जिन्हें $ rootScope ऑब्जेक्ट पर निकाल दिया गया है।

$ rootScope दो ईवेंट डिस्पैचर प्रदान करता है जिसे बुलाया जाता है $emit and $broadcastजो डिस्पैचिंग इवेंट्स (कस्टम इवेंट्स हो सकते हैं) के लिए जिम्मेदार हैं और $rootScope.$onईवेंट श्रोता को जोड़ने के लिए फ़ंक्शन का उपयोग करते हैं।


0

आपको सेवा का उपयोग करना चाहिए, क्योंकि $rootscopeपूरे एप्लिकेशन से पहुंच है, और यह लोड बढ़ाता है, या यदि आपका डेटा अधिक नहीं है, तो आप rootparams का उपयोग करें।


0
function mySrvc() {
  var callback = function() {

  }
  return {
    onSaveClick: function(fn) {
      callback = fn;
    },
    fireSaveClick: function(data) {
      callback(data);
    }
  }
}

function controllerA($scope, mySrvc) {
  mySrvc.onSaveClick(function(data) {
    console.log(data)
  })
}

function controllerB($scope, mySrvc) {
  mySrvc.fireSaveClick(data);
}

0

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

पहले हम एक नियंत्रक से एक फ़ंक्शन कहते हैं।

var myApp = angular.module('sample', []);
myApp.controller('firstCtrl', function($scope) {
    $scope.sum = function() {
        $scope.$emit('sumTwoNumber', [1, 2]);
    };
});
myApp.controller('secondCtrl', function($scope) {
    $scope.$on('sumTwoNumber', function(e, data) {
        var sum = 0;
        for (var a = 0; a < data.length; a++) {
            sum = sum + data[a];
        }
        console.log('event working', sum);

    });
});

तुम भी $ गुंजाइश के स्थान पर $ rootScope का उपयोग कर सकते हैं। तदनुसार अपने नियंत्रक का उपयोग करें।

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