Frage Arbeiten mit $ scope. $ Emit und $ scope. $ On


Wie kann ich meine senden? $scope Objekt von einem Controller zu einem anderen mit .$emit und .$on Methoden?

function firstCtrl($scope) {
    $scope.$emit('someEvent', [1,2,3]);
}

function secondCtrl($scope) {
    $scope.$on('someEvent', function(mass) { console.log(mass); });
}

Es funktioniert nicht so, wie ich denke, dass es sollte. Wie macht $emit und $on Arbeit?


844
2018-01-24 13:03


Ursprung


Antworten:


Zuallererst spielt die Eltern-Kind-Beziehung eine Rolle. Sie haben zwei Möglichkeiten, ein Ereignis auszulösen:

  • $broadcast - Sendet das Ereignis nach unten an alle untergeordneten Bereiche,
  • $emit - Versendet das Ereignis über die Bereichshierarchie nach oben.

Ich weiß nichts über Ihre Controller (Scopes) Relation, aber es gibt mehrere Möglichkeiten:

  1. Wenn Umfang von firstCtrl ist Elternteil der secondCtrl Umfang sollte dein Code sein Arbeit durch Ersetzen $emit durch $broadcast im firstCtrl:

    function firstCtrl($scope)
    {
        $scope.$broadcast('someEvent', [1,2,3]);
    }
    
    function secondCtrl($scope)
    {
        $scope.$on('someEvent', function(event, mass) { console.log(mass); });
    }
    
  2. Falls zwischen Ihren Bereichen keine Eltern-Kind-Beziehung besteht kann spritzen $rootScope in den Controller und übertragen das Ereignis für alle untergeordneten Bereiche (d. h. auch secondCtrl).

    function firstCtrl($rootScope)
    {
        $rootScope.$broadcast('someEvent', [1,2,3]);
    }
    
  3. Schließlich, wenn Sie das Ereignis vom Child Controller aus versenden müssen Bereiche nach oben können Sie verwenden $scope.$emit. Wenn Umfang von firstCtrl ist Elternteil der secondCtrl Umfang:

    function firstCtrl($scope)
    {
        $scope.$on('someEvent', function(event, data) { console.log(data); });
    }
    
    function secondCtrl($scope)
    {
        $scope.$emit('someEvent', [1,2,3]);
    }
    

1465
2018-01-24 13:41



Ich würde zusätzlich eine vierte Option als eine bessere Alternative zu den vorgeschlagenen Optionen von @zbynour vorschlagen.

Benutzen $rootScope.$emit eher, als $rootScope.$broadcast unabhängig von der Beziehung zwischen Sender und Empfänger. Auf diese Weise bleibt das Ereignis innerhalb der Menge von $rootScope.$$listeners während mit $rootScope.$broadcast Das Ereignis wird an alle untergeordneten Bereiche weitergegeben, von denen die meisten wahrscheinlich ohnehin keine Zuhörer dieses Ereignisses sind. Und natürlich am Ende des Empfangscontrollers $rootScope.$on.

Bei dieser Option müssen Sie daran denken, die rootScope-Listener des Controllers zu zerstören:

var unbindEventHandler = $rootScope.$on('myEvent', myHandler);
$scope.$on('$destroy', function () {
  unbindEventHandler();
});

140
2018-04-06 19:34



Wie kann ich mein $ scope-Objekt mit den Methoden $ emit und. $ On von einem Controller an einen anderen senden?

Sie können jedes gewünschte Objekt innerhalb der Hierarchie Ihrer App senden, einschließlich $ Bereich.

Hier ist eine kurze Vorstellung davon, wie Übertragung und emittieren Arbeit.

Beachten Sie die folgenden Knoten; alle verschachtelt in Knoten 3. Sie verwenden Übertragung und emittieren wenn du dieses Szenario hast.

Hinweis: Die Anzahl jedes Knotens in diesem Beispiel ist beliebig; es könnte leicht die Nummer eins sein; die Nummer zwei; oder auch die Nummer 1,348. Jede Zahl ist nur eine Kennung für dieses Beispiel. Der Zweck dieses Beispiels ist es, die Verschachtelung von eckigen Controllern / Direktiven zu zeigen.

                 3
           ------------
           |          |
         -----     ------
         1   |     2    |
      ---   ---   ---  ---
      | |   | |   | |  | |

Sieh dir diesen Baum an. Wie beantworten Sie die folgenden Fragen?

Hinweis: Es gibt andere Möglichkeiten, diese Fragen zu beantworten, aber hier werden wir diskutieren Übertragung und emittieren. Wenn Sie unter dem Text lesen, nehmen Sie an, dass jede Zahl eine eigene Datei (directive, controller) e.x. one.js, two.js, three.js.

Wie funktioniert Knoten? 1 Sprich mit Knoten 3?

Im Ordner ein.js

scope.$emit('messageOne', someValue(s));

Im Ordner drei .js - der oberste Knoten für alle untergeordneten Knoten, die für die Kommunikation benötigt werden.

scope.$on('messageOne', someValue(s));

Wie spricht Knoten 2 mit Knoten 3?

Im Ordner zwei .js

scope.$emit('messageTwo', someValue(s));

Im Ordner drei .js - der oberste Knoten für alle untergeordneten Knoten, die für die Kommunikation benötigt werden.

scope.$on('messageTwo', someValue(s));

Wie spricht Knoten 3 mit Knoten 1 und / oder Knoten 2?

Im Ordner drei .js - der oberste Knoten für alle untergeordneten Knoten, die für die Kommunikation benötigt werden.

scope.$broadcast('messageThree', someValue(s));

Im Ordner ein.js && zwei .js für welche Datei Sie die Nachricht abfangen wollen oder beides.

scope.$on('messageThree', someValue(s));

Wie spricht Knoten 2 mit Knoten 1?

Im Ordner zwei .js

scope.$emit('messageTwo', someValue(s));

Im Ordner drei .js - der oberste Knoten für alle untergeordneten Knoten, die für die Kommunikation benötigt werden.

scope.$on('messageTwo', function( event, data ){
  scope.$broadcast( 'messageTwo', data );
});

Im Ordner ein.js

scope.$on('messageTwo', someValue(s));

JEDOCH

Wenn Sie alle diese verschachtelten untergeordneten Knoten versuchen, so zu kommunizieren, werden Sie schnell viele sehen $ on's, $ Rundfunksendungen, und $ emittiert.

Hier ist was ich gerne mache.

Im obersten Elternknoten ( 3 in diesem Fall ...), der Ihr Eltern-Controller sein könnte ...

Also, in der Datei drei .js

scope.$on('pushChangesToAllNodes', function( event, message ){
  scope.$broadcast( message.name, message.data );
});

Jetzt in einem der untergeordneten Knoten müssen Sie nur $ emittieren die Nachricht oder fangen sie mit $ auf.

HINWEIS: Es ist normalerweise ziemlich einfach, in einem verschachtelten Pfad ohne Verwendung zu übersprechen $ emittieren, $ Rundfunk, oder $ aufDies bedeutet, dass die meisten Anwendungsfälle für den Fall, dass Sie versuchen, Knoten zu erhalten 1 mit Knoten kommunizieren 2 oder umgekehrt.

Wie spricht Knoten 2 mit Knoten 1?

Im Ordner zwei .js

scope.$emit('pushChangesToAllNodes', sendNewChanges());

function sendNewChanges(){ // for some event.
  return { name: 'talkToOne', data: [1,2,3] };
}

Im Ordner drei .js - der oberste Knoten für alle untergeordneten Knoten, die für die Kommunikation benötigt werden.

Wir haben das schon erledigt, erinnerst du dich?

Im Ordner ein.js

scope.$on('talkToOne', function( event, arrayOfNumbers ){
  arrayOfNumbers.forEach(function(number){
    console.log(number);
  });
});

Sie müssen immer noch verwenden $ auf Mit jedem spezifischen Wert, den Sie fangen möchten, können Sie jetzt in einem der Knoten erstellen, was Sie wollen, ohne sich darum kümmern zu müssen, wie Sie die Nachricht über die Lücke des übergeordneten Knotens erhalten, wenn wir das generische fangen und senden pushChangesToAllNodes.

Hoffe das hilft...


107
2017-07-11 14:47



Senden $scope object von einem Controller zum anderen werde ich darüber diskutieren $rootScope.$broadcast und $rootScope.$emit hier, wie sie am meisten benutzt werden.

Fall 1:

$ rootScope. $ sendung: -

$rootScope.$broadcast('myEvent',$scope.data);//Here `myEvent` is event name

$rootScope.$on('myEvent', function(event, data) {} //listener on `myEvent` event

$rootScope Zuhörer werden nicht automatisch zerstört. Sie müssen es mit zerstören $destroy. Es ist besser zu benutzen $scope.$on als Zuhörer auf $scope werden automatisch zerstört, d. h. sobald $ scope zerstört wird.

$scope.$on('myEvent', function(event, data) {}

Oder,

  var customeEventListener = $rootScope.$on('myEvent', function(event, data) {

  }
  $scope.$on('$destroy', function() {
        customeEventListener();
  });

Fall 2: 

$ rootScope. $ emittieren:

   $rootScope.$emit('myEvent',$scope.data);

   $rootScope.$on('myEvent', function(event, data) {}//$scope.$on not works

Der Hauptunterschied zwischen $ emit und $ broadcast besteht darin, dass das $ rootScope. $ Emitter -Ereignis mit $ rootScope. $ On gehört werden muss, da das emittierte Ereignis niemals durch die Oszilloskop-Baumstruktur herunterkommt..
In diesem Fall müssen Sie auch den Hörer wie bei $ broadcast zerstören.

Bearbeiten:

Ich bevorzuge es nicht zu benutzen $rootScope.$broadcast + $scope.$on aber benutze es    $rootScope.$emit+ $rootScope.$on. Das $rootScope.$broadcast + $scope.$on Die Kombination kann schwerwiegende Leistungsprobleme verursachen. Das ist   weil das Ereignis durch alle Bereiche blubbern wird.

Bearbeiten 2:

Das in dieser Antwort angesprochene Problem wurde in angular.js behoben   Version 1.2.7. $ broadcast verhindert jetzt das Übersprudeln über nicht registrierte Bereiche   und läuft genauso schnell wie $ emit.


35
2018-04-02 18:54



Sie müssen $ rootScope verwenden, um Ereignisse zwischen Controllern in derselben App zu senden und zu erfassen. Inject $ rootScope-Abhängigkeit zu Ihren Controllern. Hier ist ein funktionierendes Beispiel.

app.controller('firstCtrl', function($scope, $rootScope) {        
        function firstCtrl($scope) {
        {
            $rootScope.$emit('someEvent', [1,2,3]);
        }
}

app.controller('secondCtrl', function($scope, $rootScope) {
        function secondCtrl($scope)
        {
            $rootScope.$on('someEvent', function(event, data) { console.log(data); });
        }
}

Ereignisse, die mit dem $ scope-Objekt verknüpft sind, funktionieren nur im Owner-Controller. Die Kommunikation zwischen den Controllern erfolgt über $ rootScope oder Services.


10
2018-01-10 07:01



Sie können einen Dienst von Ihrem Controller aufrufen, der eine Zusage zurückgibt und sie dann in Ihrem Controller verwendet. Und weitere Verwendung $emit oder $broadcast um andere Controller darüber zu informieren. In meinem Fall musste ich über meinen Dienst http-Anrufe tätigen, also habe ich so etwas gemacht:

function ParentController($scope, testService) {
    testService.getList()
        .then(function(data) {
            $scope.list = testService.list;
        })
        .finally(function() {
            $scope.$emit('listFetched');
        })


    function ChildController($scope, testService) {
        $scope.$on('listFetched', function(event, data) {
            // use the data accordingly
        })
    }

und mein Service sieht so aus

    app.service('testService', ['$http', function($http) {

        this.list = [];

        this.getList = function() {
            return $http.get(someUrl)
                .then(function(response) {
                    if (typeof response.data === 'object') {
                        list = response.data.results;

                        return response.data;
                    } else {
                        // invalid response
                        return $q.reject(response.data);
                    }

                }, function(response) {
                    // something went wrong
                    return $q.reject(response.data);
                });

        }

    }])

6
2018-03-20 11:19



Das ist meine Funktion:

$rootScope.$emit('setTitle', newVal.full_name);

$rootScope.$on('setTitle', function(event, title) {
    if (scope.item) 
        scope.item.name = title;
    else 
        scope.item = {name: title};
});

3
2017-09-11 10:37



<!DOCTYPE html>
<html>

<head>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
var app = angular.module('MyApp',[]);
app.controller('parentCtrl',function($scope){
  $scope.$on('MyEvent',function(event,data){    
    $scope.myData = data;
  });
 });

app.controller('childCtrl',function($scope){
  $scope.fireEvent = function(){ 
  $scope.$emit('MyEvent','Any Data');
  }  
 });
</script>
</head>
<body ng-app="MyApp">
<div ng-controller="parentCtrl" ng-model="myName">

{{myData}}

 <div ng-controller="childCtrl">
   <button ng-click="fireEvent()">Fire Event</button>
 </div>

</div>
</body>
</html>

3
2018-04-13 13:25