javascript - new - Travailler avec $ scope. $ Emit et $ scope. $ On




scope new (9)

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 de la façon dont la diffusion et l' émission fonctionnent.

Notez les nœuds ci-dessous; tous imbriqués dans le nœud 3. Vous utilisez broadcast et émettez lorsque 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 existe d'autres façons de répondre à ces questions, mais ici, nous discuterons de la diffusion et de l' émission . De plus, en lisant le texte ci-dessous, supposons que chaque numéro possède son propre fichier (directive, contrôleur) ex one.js, two.js, three.js.

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

Dans le fichier one.js

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

Dans le fichier three.js - le nœud supérieur à 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 supérieur à 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 supérieur à 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 capturer 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 supérieur à 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 ceci, vous verrez rapidement de nombreux $ 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 avez seulement besoin de $ émettre le message ou l'attraper en utilisant $ on .

REMARQUE: Il est généralement très facile de croiser un chemin imbriqué sans $ emit , $ broadcast ou $ on , ce qui signifie que la plupart des cas d'utilisation sont nécessaires lorsque le nœud 1 communique avec le nœud 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 supérieur à 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 aurez toujours besoin d'utiliser $ on avec chaque valeur spécifique que vous voulez attraper, mais maintenant vous pouvez créer ce que vous voulez dans n'importe lequel des nœuds sans avoir à vous soucier de la façon de passer le message à travers le nœud parent. le pushChangesToAllNodes générique.

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

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

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 $emit et $on travail?


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

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

Utilisez $rootScope.$emit plutôt que $rootScope.$broadcast indépendamment de la relation entre le transmetteur et le contrôleur de réception. De cette façon, l'événement reste dans l'ensemble des $rootScope.$$listeners alors qu'avec $rootScope.$broadcast l'événement se propage à toutes les portées 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();
});

Le code ci-dessous montre les deux sous-contrôleurs depuis lesquels les événements sont envoyés vers le contrôleur parent (rootScope)

<body ng-app="App">

    <div ng-controller="parentCtrl">

        <p>City : {{city}} </p>
        <p> Address : {{address}} </p>

        <div ng-controller="subCtrlOne">
            <input type="text" ng-model="city" />
            <button ng-click="getCity(city)">City !!!</button>
        </div>

        <div ng-controller="subCtrlTwo">

            <input type="text" ng-model="address" />
            <button ng-click="getAddrress(address)">Address !!!</button>

        </div>

    </div>

</body>

var App = angular.module('App', []);

// parent controller
App.controller('parentCtrl', parentCtrl);

parentCtrl.$inject = ["$scope"];

function parentCtrl($scope) {

    $scope.$on('cityBoom', function(events, data) {
        $scope.city = data;
    });

    $scope.$on('addrBoom', function(events, data) {
        $scope.address = data;
    });
}

// sub controller one

App.controller('subCtrlOne', subCtrlOne);

subCtrlOne.$inject = ['$scope'];

function subCtrlOne($scope) {

    $scope.getCity = function(city) {

        $scope.$emit('cityBoom', city);    
    }
}

// sub controller two

App.controller('subCtrlTwo', subCtrlTwo);

subCtrlTwo.$inject = ["$scope"];

function subCtrlTwo($scope) {

    $scope.getAddrress = function(addr) {

        $scope.$emit('addrBoom', addr);   
    }
}

http://jsfiddle.net/shushanthp/zp6v0rut/


Pour envoyer $scope object d'un contrôleur à un autre, je $rootScope.$broadcast $rootScope.$emit et $rootScope.$emit ici car ils sont utilisés le plus souvent.

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 listener ne sont pas détruits automatiquement. Vous devez le détruire en utilisant $destroy . Il est préférable d'utiliser $scope.$on Comme les écouteurs sur $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 utiliser $rootScope.$emit+ $rootScope.$on . $rootScope.$broadcast + $scope.$on combo peut causer de sérieux problèmes de performances. C'est parce que l'événement descendra dans tous les domaines.

Édition 2 :

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


Scope (s) peut être utilisé pour propager, envoyer l'événement à la portée enfants ou parent.

$ emit - propage l'événement au parent. $ broadcast - propage l'événement aux enfants. $ on - méthode pour écouter les événements, propagée par $ emit et $ broadcast.

exemple index.html :

<div ng-app="appExample" ng-controller="EventCtrl">
      Root(Parent) scope count: {{count}}
  <div>
      <button ng-click="$emit('MyEvent')">$emit('MyEvent')</button>
      <button ng-click="$broadcast('MyEvent')">$broadcast('MyEvent')</button><br>

      Childrent scope count: {{count}} 
  </div>
</div>

exemple app.js :

angular.module('appExample', [])
.controller('EventCtrl', ['$scope', function($scope) {
  $scope.count = 0;
  $scope.$on('MyEvent', function() {
    $scope.count++;
  });
}]);

Ici vous pouvez tester le code: http://jsfiddle.net/zp6v0rut/41/


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

  • $broadcast - envoie l'événement vers tous les 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 la portée secondCtrl , votre code devrait fonctionner en remplaçant $emit firstCtrl 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 portées, vous pouvez injecter $rootScope dans le contrôleur et diffuser l'événement à toutes les portées enfant (ie aussi secondCtrl ).

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

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

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.


<!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>






angularjs