$ पर और कोणीय में $ प्रसारण


282

मेरे पास अलग-अलग विचारों के साथ एक पाद लेख और कोडस्कैनकंट्रोलर है।

angular.module('myApp').controller('footerController', ["$scope", function($scope) {}]);

angular.module('myApp').controller('codeScannerController', ["$scope", function($scope) {
console.log("start");
$scope.startScanner = function(){...

जब मैं <li>footer.html पर क्लिक करता हूं, तो मुझे इस घटना को codeScannerController में प्राप्त करना चाहिए।

<li class="button" ng-click="startScanner()">3</li>

मुझे लगता है कि यह महसूस किया जा सकता है $onऔर $broadcast, लेकिन मैं नहीं जानता कि कैसे और कहीं भी उदाहरण नहीं मिल सकता है।

जवाबों:


631

यदि आप $broadcastउपयोग करना चाहते हैं $rootScope:

$scope.startScanner = function() {

    $rootScope.$broadcast('scanner-started');
}

और फिर प्राप्त करने के लिए, $scopeअपने नियंत्रक का उपयोग करें :

$scope.$on('scanner-started', function(event, args) {

    // do what you want to do
});

यदि आप चाहते हैं कि आप तर्क दे सकें जब आप $broadcast:

$rootScope.$broadcast('scanner-started', { any: {} });

और फिर उन्हें प्राप्त करें:

$scope.$on('scanner-started', function(event, args) {

    var anyThing = args.any;
    // do what you want to do
});

स्कोप डॉक्स के अंदर इसके लिए प्रलेखन ।


2
आप अपनी पसंद की किसी भी घटना को नाम दे सकते हैं।
डेविन ट्रेटन

5
सुनिश्चित करें कि आप $ गुंजाइश हैं। $ apply (); आपके परिवर्तन!
इस्माइल

4
@ इस्माइल क्यों ... और कहां?
जाॅन

7
क्या प्रसारण संदेश को हार्डकोड करने के बजाय इन तारों को संग्रहीत करने के लिए कोई अनुशंसित प्रथाएं हैं?
5

8
@ आईमेल $scope.$apply()केवल तभी आवश्यक होता है जब कोणीय ढांचे के बाहर के मॉडल को बदलना (जैसे एक सेटटाइमआउट, एक डायलॉग कॉलबैक, या एक अजाक्स कॉलबैक), दूसरे शब्दों $apply()में सभी कोड .$on()समाप्त होने के बाद पहले से ही चालू हो जाता है।
th3uiguy

97

सबसे पहले, का एक संक्षिप्त विवरण $on(), $broadcast()और$emit() :

  • .$on(name, listener) - दिए गए द्वारा एक विशिष्ट घटना के लिए सुनता है name
  • .$broadcast(name, args)- $scopeसभी बच्चों के माध्यम से एक घटना को नीचे प्रसारित करें
  • .$emit(name, args)- $scopeसभी माता-पिता सहित पदानुक्रम तक एक घटना का उत्सर्जन करें$rootScope

निम्न HTML के आधार पर ( पूर्ण उदाहरण यहां देखें ):

<div ng-controller="Controller1">
    <button ng-click="broadcast()">Broadcast 1</button>
    <button ng-click="emit()">Emit 1</button>
</div>

<div ng-controller="Controller2">
    <button ng-click="broadcast()">Broadcast 2</button>
    <button ng-click="emit()">Emit 2</button>
    <div ng-controller="Controller3">
        <button ng-click="broadcast()">Broadcast 3</button>
        <button ng-click="emit()">Emit 3</button>
        <br>
        <button ng-click="broadcastRoot()">Broadcast Root</button>
        <button ng-click="emitRoot()">Emit Root</button>
    </div>
</div>

फायर की गई घटनाएं $scopesनिम्नानुसार चलेंगी:

  • प्रसारण 1 - केवल नियंत्रक 1 द्वारा देखा जाएगा $scope
  • एमिट 1 - $scopeतब नियंत्रक 1 द्वारा देखा जाएगा$rootScope
  • प्रसारण 2 - नियंत्रक 2 $scopeतब नियंत्रक 3 द्वारा देखा जाएगा$scope
  • एमिट 2 - $scopeतब नियंत्रक 2 द्वारा देखा जाएगा$rootScope
  • प्रसारण 3 - केवल नियंत्रक 3 द्वारा देखा जाएगा $scope
  • Emit 3 - नियंत्रक 3 $scope, नियंत्रक 2 द्वारा $scopeतब देखा जाएगा$rootScope
  • प्रसारण रूट - द्वारा देखा जाएगा $rootScopeऔर $scopeसभी नियंत्रकों (1, तो 2 3)
  • एमिट रूट - द्वारा ही देखा जाएगा $rootScope

घटनाओं को फिर से शुरू करने के लिए जावास्क्रिप्ट (फिर, आप यहां एक काम करने वाला उदाहरण देख सकते हैं ):

app.controller('Controller1', ['$scope', '$rootScope', function($scope, $rootScope){
    $scope.broadcastAndEmit = function(){
        // This will be seen by Controller 1 $scope and all children $scopes 
        $scope.$broadcast('eventX', {data: '$scope.broadcast'});

        // Because this event is fired as an emit (goes up) on the $rootScope,
        // only the $rootScope will see it
        $rootScope.$emit('eventX', {data: '$rootScope.emit'});
    };
    $scope.emit = function(){
        // Controller 1 $scope, and all parent $scopes (including $rootScope) 
        // will see this event
        $scope.$emit('eventX', {data: '$scope.emit'});
    };

    $scope.$on('eventX', function(ev, args){
        console.log('eventX found on Controller1 $scope');
    });
    $rootScope.$on('eventX', function(ev, args){
        console.log('eventX found on $rootScope');
    });
}]);

मैं अपने ऐप के पदानुक्रम की कल्पना कैसे कर सकता हूं जो आपने दिया है। नियंत्रक माता-पिता या बच्चा कैसे हो सकता है। ?? मैं जो कहना चाह रहा हूं वह यह है कि मेरे पास राज्य की श्रृंखला है। LoginCtrl -> homeCrl -> notificationCtrl और इतने पर।
HIRA ठाकुर

26

एक बात जो आपको पता होनी चाहिए वह है $ उपसर्ग एक कोणीय विधि को संदर्भित करता है, $ $ उपसर्ग को कोणीय विधियों को संदर्भित करता है जिसे आपको उपयोग करने से बचना चाहिए।

नीचे एक उदाहरण टेम्पलेट और इसके नियंत्रक हैं, हम यह पता लगाएंगे कि हम जो चाहते हैं, उसे प्राप्त करने के लिए $ प्रसारण / $ कैसे मदद कर सकते हैं।

<div ng-controller="FirstCtrl">
    <input ng-model="name"/> 
    <button ng-click="register()">Register </button>
</div>

<div ng-controller="SecondCtrl">
    Registered Name: <input ng-model="name"/> 
</div>

नियंत्रक हैं

app.controller('FirstCtrl', function($scope){
    $scope.register = function(){

    }
});

app.controller('SecondCtrl', function($scope){

});

आपसे मेरा सवाल यह है कि जब कोई उपयोगकर्ता क्लिक करता है तो आप दूसरे नियंत्रक को नाम कैसे देते हैं? आप कई समाधानों के साथ आ सकते हैं, लेकिन हम जो उपयोग करने जा रहे हैं वह $ प्रसारण और $ का उपयोग कर रहा है।

$ प्रसारण बनाम $ एमिट

हमें किसका उपयोग करना चाहिए? $ ब्रॉडकास्ट सभी बच्चों के प्रमुख तत्वों को प्रसारित करेगा और $ एमिट सभी पूर्वज डोम तत्वों को विपरीत दिशा में प्रसारित करेगा।

$ एमिट या $ प्रसारण के बीच निर्णय लेने से बचने का सबसे अच्छा तरीका है $ rootScope से चैनल और अपने सभी बच्चों के लिए $ प्रसारण का उपयोग करें। जिससे हमारे मामले बहुत आसान हो जाते हैं क्योंकि हमारे प्रमुख तत्व भाई बहन हैं।

$ RootScope जोड़ना और $ प्रसारण की सुविधा देता है

app.controller('FirstCtrl', function($rootScope, $scope){
    $scope.register = function(){
        $rootScope.$broadcast('BOOM!', $scope.name)
    }
});

ध्यान दें कि हमने $ rootScope जोड़ा है और अब हम $ प्रसारण (प्रसारण नाम, तर्क) का उपयोग कर रहे हैं। प्रसारणनाम के लिए, हम इसे एक अनोखा नाम देना चाहते हैं ताकि हम अपने सेकंडक्रेडल में उस नाम को पकड़ सकें। मैंने BOOM को चुना है! सिर्फ मनोरंजन के लिए। दूसरा तर्क 'तर्क' हमें श्रोताओं को मान देने की अनुमति देता है।

हमारा प्रसारण प्राप्त करना

हमारे दूसरे कंट्रोलर में, हमें अपने प्रसारण को सुनने के लिए कोड सेट करना होगा

app.controller('SecondCtrl', function($scope){
  $scope.$on('BOOM!', function(events, args){
    console.log(args);
    $scope.name = args; //now we've registered!
  })
});

यह वास्तव में इतना आसान है। लाइव उदाहरण

समान परिणाम प्राप्त करने के अन्य तरीके

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

आप आमतौर पर एक सेवा का उपयोग करके या अपने नियंत्रकों को सरल करके एक ही काम कर सकते हैं। हम इस पर विस्तार से चर्चा नहीं करेंगे, लेकिन मुझे लगा कि मैं इसे पूर्णता के लिए उल्लेख करूंगा।

अंत में, '$ नष्ट' सुनने के लिए एक बहुत ही उपयोगी प्रसारण को ध्यान में रखें फिर आप $ का अर्थ देख सकते हैं कि यह विक्रेता कोड द्वारा बनाई गई विधि या वस्तु है। जब भी कोई नियंत्रक नष्ट हो जाता है, तब भी $ नष्ट हो जाता है, आप यह जानना चाहते हैं कि आपका नियंत्रक हटा दिया जाए।


2
एक चेतावनी के रूप में, अपने ऐप में बहुत सारे प्रसारण / उत्सर्जन का उपयोग न करने का प्रयास करें। वे विशेष रूप से एक बड़े ऐप में प्रबंधित करने के लिए बेहद कठिन हो सकते हैं क्योंकि इन घटनाओं की जड़ों को ट्रेस करना बहुत कठिन काम है।
यांग ली

1
//Your broadcast in service

(function () { 
    angular.module('appModule').factory('AppService', function ($rootScope, $timeout) {

    function refreshData() {  
        $timeout(function() {         
            $rootScope.$broadcast('refreshData');
        }, 0, true);      
    }

    return {           
        RefreshData: refreshData
    };
}); }());

//Controller Implementation
 (function () {
    angular.module('appModule').controller('AppController', function ($rootScope, $scope, $timeout, AppService) {            

       //Removes Listeners before adding them 
       //This line will solve the problem for multiple broadcast call                             
       $scope.$$listeners['refreshData'] = [];

       $scope.$on('refreshData', function() {                                                    
          $scope.showData();             
       });

       $scope.onSaveDataComplete = function() { 
         AppService.RefreshData();
       };
    }); }());
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.