Question Travailler avec $ scope. $ Emit et $ scope. $ On


Comment puis-je envoyer mon $scope objet d'un contrôleur à l'autre en utilisant .$emit et .$on méthodes?

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

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

Cela ne fonctionne pas comme je le pense. Comment faire $emit et $on travail?


844
2018-01-24 13:03


origine


Réponses:


Tout d'abord, la relation de portée parent-enfant est importante. Vous avez deux possibilités pour émettre un événement:

  • $broadcast - distribue l'événement vers tous les domaines d'application pour enfants,
  • $emit - envoie l'événement vers le haut à travers la hiérarchie de portée.

Je ne sais rien de la relation de vos contrôleurs (oscilloscopes), mais il y a plusieurs options:

  1. Si la portée de firstCtrl est parent de secondCtrl portée, votre code devrait travailler en remplaçant $emit par $broadcast dans firstCtrl:

    function firstCtrl($scope)
    {
        $scope.$broadcast('someEvent', [1,2,3]);
    }
    
    function secondCtrl($scope)
    {
        $scope.$on('someEvent', function(event, mass) { console.log(mass); });
    }
    
  2. Dans le cas où il n'y a pas de relation parent-enfant entre vos étendues peut injecter $rootScope dans le contrôleur et diffusé l'événement à tous les champs d'application des enfants (c'est-à-dire secondCtrl).

    function firstCtrl($rootScope)
    {
        $rootScope.$broadcast('someEvent', [1,2,3]);
    }
    
  3. Enfin, lorsque vous devez envoyer l'événement depuis un contrôleur enfant vers les portées vers le haut, vous pouvez utiliser $scope.$emit. Si la portée de firstCtrl est parent de secondCtrl portée:

    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



Je proposerais en outre une 4ème option comme une meilleure alternative aux options proposées par @zbynour.

Utilisation $rootScope.$emit plutôt que $rootScope.$broadcast indépendamment de la relation entre transmettre et recevoir le contrôleur. De cette façon, l'événement reste dans l'ensemble des $rootScope.$$listeners alors qu'avec $rootScope.$broadcast l'événement se propage à tous les enfants, dont la plupart ne seront probablement pas les auditeurs de cet événement. Et bien sûr, dans la fin du contrôleur de réception, vous utilisez simplement $rootScope.$on.

Pour cette option, vous devez vous souvenir de détruire les écouteurs rootScope du contrôleur:

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

140
2018-04-06 19:34



Comment puis-je envoyer mon objet $ scope d'un contrôleur à un autre en utilisant. $ Emit et. $ On methods?

Vous pouvez envoyer n'importe quel objet dans la hiérarchie de votre application, y compris $ scope.

Voici une idée rapide sur la façon dont diffuser et émettre travail.

Notez les nœuds ci-dessous; tous imbriqués dans le nœud 3. Vous utilisez diffuser et émettre quand vous avez ce scénario.

Remarque: Le nombre de chaque noeud dans cet exemple est arbitraire; ça pourrait facilement être le numéro un; le numéro deux; ou même le nombre 1,348. Chaque nombre est juste un identifiant pour cet exemple. Le but de cet exemple est d'afficher l'imbrication des contrôleurs / directives angulaires.

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

Découvrez cet arbre. Comment répondez-vous aux questions suivantes?

Remarque: Il y a d'autres façons de répondre à ces questions, mais ici nous discuterons diffuser et émettre. De plus, en lisant le texte ci-dessous, supposons que chaque numéro possède son propre fichier (directive, contrôleur) e.x. one.js, two.js, three.js.

Comment noeud 1 parler au noeud 3?

Dans le fichier one.js

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

Dans le fichier three.js - le nœud le plus élevé de tous les nœuds enfants nécessaires pour communiquer.

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

Comment le nœud 2 parle-t-il au nœud 3?

Dans le fichier two.js

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

Dans le fichier three.js - le nœud le plus élevé de tous les nœuds enfants nécessaires pour communiquer.

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

Comment le nœud 3 parle-t-il au nœud 1 et / ou au nœud 2?

Dans le fichier three.js - le nœud le plus élevé de tous les nœuds enfants nécessaires pour communiquer.

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

Dans le fichier one.js && two.js quel que soit le fichier que vous voulez attraper le message ou les deux.

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

Comment le nœud 2 parle-t-il au nœud 1?

Dans le fichier two.js

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

Dans le fichier three.js - le nœud le plus élevé de tous les nœuds enfants nécessaires pour communiquer.

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

Dans le fichier one.js

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

TOUTEFOIS

Lorsque vous avez tous ces nœuds enfants imbriqués essayant de communiquer comme ça, vous verrez rapidement $ on, $ broadcast, et $ emit.

Voici ce que j'aime faire.

Dans le NŒUD PARENT le plus élevé ( 3 dans ce cas ...), qui peut être votre contrôleur parent ...

Donc, dans le fichier three.js

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

Maintenant, dans l'un des nœuds enfants, vous devez seulement $ emit le message ou l'attraper en utilisant $ sur.

REMARQUE: Il est normalement assez facile de croiser un chemin imbriqué sans utiliser $ emit, $ broadcast, ou $ sur, ce qui signifie que la plupart des cas d'utilisation sont pour quand vous essayez d'obtenir le noeud 1 pour communiquer avec le noeud 2 ou vice versa.

Comment le nœud 2 parle-t-il au nœud 1?

Dans le fichier two.js

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

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

Dans le fichier three.js - le nœud le plus élevé de tous les nœuds enfants nécessaires pour communiquer.

Nous avons déjà manipulé celui-ci rappelez-vous?

Dans le fichier one.js

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

Vous devrez toujours utiliser $ sur avec chaque valeur spécifique que vous voulez attraper, mais maintenant vous pouvez créer ce que vous voulez dans l'un des nœuds sans avoir à vous soucier de la façon de passer le message à travers le trou du nœud parent comme nous attrapons et diffusons le générique pushChangesToAllNodes.

J'espère que cela t'aides...


107
2017-07-11 14:47



Envoyer $scope object d'un contrôleur à l'autre, je vais discuter à propos de $rootScope.$broadcast et $rootScope.$emit ici comme ils sont utilisés le plus.

Cas 1:

$ rootScope. $ diffusion: -

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

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

$rootScope les écouteurs ne sont pas détruits automatiquement. Vous devez le détruire en utilisant $destroy. Il vaut mieux utiliser $scope.$on en tant qu'auditeurs $scope sont détruits automatiquement, c'est-à-dire dès que $ scope est détruit.

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

Ou,

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

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

Cas 2: 

$ rootScope. $ emit:

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

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

La principale différence entre $ emit et $ broadcast est que $ rootScope. $ Emit event doit être écouté avec $ rootScope. $ On, car l'événement émis ne descend jamais dans l'arborescence de la portée..
Dans ce cas également, vous devez détruire l'écouteur comme dans le cas de $ broadcast.

Modifier:

Je préfère ne pas utiliser $rootScope.$broadcast + $scope.$on mais utilisez    $rootScope.$emit+ $rootScope.$on. le $rootScope.$broadcast + $scope.$on Le combo peut causer de sérieux problèmes de performance. C'est   car l'événement se déroulera dans tous les domaines.

Modifier 2:

Le problème abordé dans cette réponse a été résolu dans angular.js   version 1.2.7. $ broadcast évite maintenant de faire des bulles sur des portées non enregistrées   et fonctionne tout aussi rapidement que $ emit.


35
2018-04-02 18:54



Vous devez utiliser $ rootScope pour envoyer et capturer des événements entre contrôleurs dans la même application. Injectez la dépendance $ rootScope à vos contrôleurs. Voici un exemple de travail.

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); });
        }
}

Les événements liés à l'objet $ scope fonctionnent uniquement dans le contrôleur propriétaire. La communication entre les contrôleurs se fait via $ rootScope ou Services.


10
2018-01-10 07:01



Vous pouvez appeler un service de votre contrôleur qui renvoie une promesse, puis l'utiliser dans votre contrôleur. Et plus loin $emit ou $broadcast informer les autres contrôleurs à ce sujet. Dans mon cas, j'ai dû faire des appels http via mon service, donc j'ai fait quelque chose comme ça:

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
        })
    }

et mon service ressemble à ceci

    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



C'est ma fonction:

$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