javascript - example - Trabajar con $ scope. $ Emit y $ scope. $ En



scope apply (9)

¿Cómo puedo enviar mi objeto $scope de un controlador a otro usando los métodos .$emit y .$on On?

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

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

No funciona como creo que debería. ¿Cómo funcionan $emit y $on trabajo?

https://code.i-harness.com


¿Cómo puedo enviar mi objeto $ scope de un controlador a otro usando los métodos. $ Emit y. $ On?

Puede enviar cualquier objeto que desee dentro de la jerarquía de su aplicación, incluido $ scope .

Aquí hay una idea rápida de cómo funcionan la emisión y la emisión .

Note los nodos abajo; todos anidados dentro del nodo 3. Usted usa transmisión y emisión cuando tiene este escenario.

Nota: El número de cada nodo en este ejemplo es arbitrario; fácilmente podría ser el número uno; el número dos; O incluso el número 1.348. Cada número es solo un identificador para este ejemplo. El punto de este ejemplo es mostrar el anidamiento de los controladores / directivas angulares.

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

Echa un vistazo a este árbol. ¿Cómo respondes las siguientes preguntas?

Nota: Hay otras formas de responder a estas preguntas, pero aquí hablaremos sobre transmisión y emisión . Además, cuando lea el texto debajo, suponga que cada número tiene su propio archivo (directiva, controlador) ex one.js, two.js, three.js.

¿Cómo habla el nodo 1 al nodo 3 ?

En el archivo one.js

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

En el archivo three.js : el nodo superior a todos los nodos secundarios necesarios para la comunicación.

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

¿Cómo habla el nodo 2 al nodo 3?

En el archivo two.js

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

En el archivo three.js : el nodo superior a todos los nodos secundarios necesarios para la comunicación.

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

¿Cómo habla el nodo 3 al nodo 1 y / o el nodo 2?

En el archivo three.js : el nodo superior a todos los nodos secundarios necesarios para la comunicación.

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

En el archivo one.js && two.js, el archivo que desee capturar el mensaje o ambos.

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

¿Cómo habla el nodo 2 al nodo 1?

En el archivo two.js

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

En el archivo three.js : el nodo superior a todos los nodos secundarios necesarios para la comunicación.

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

En el archivo one.js

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

SIN EMBARGO

Cuando tenga todos estos nodos secundarios anidados intentando comunicarse de esta manera, verá rápidamente muchos $ on's , $ broadcast's y $ emit's .

Esto es lo que me gusta hacer.

En el NOMBRE DE LOS PADRES superior ( 3 en este caso ...), que puede ser su controlador principal ...

Así, en el archivo three.js

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

Ahora, en cualquiera de los nodos secundarios solo necesita $ emitir el mensaje o capturarlo usando $ on .

NOTA: normalmente es bastante fácil realizar una conversación cruzada en una ruta anidada sin usar $ emit , $ broadcast o $ on , lo que significa que la mayoría de los casos de uso son para cuando intenta que el nodo 1 se comunique con el nodo 2 o viceversa.

¿Cómo habla el nodo 2 al nodo 1?

En el archivo two.js

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

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

En el archivo three.js : el nodo superior a todos los nodos secundarios necesarios para la comunicación.

Ya manejamos esto, ¿recuerdas?

En el archivo one.js

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

Aún necesitará usar $ on con cada valor específico que desee capturar, pero ahora puede crear lo que quiera en cualquiera de los nodos sin tener que preocuparse sobre cómo hacer llegar el mensaje a través del espacio del nodo principal a medida que detectamos y transmitimos Los pushChangesToAllNodes genéricos.

Espero que esto ayude...


De acuerdo con los documentos del evento angularjs, el extremo receptor debe contener argumentos con una estructura como

@params

- El evento {Object} es el objeto de evento que contiene información sobre el evento.

- {Objetos} argumentos que son pasados ​​por el llamado (Tenga en cuenta que esto solo puede ser uno por lo que es mejor enviar siempre un objeto de diccionario)

$scope.$on('fooEvent', function (event, args) { console.log(args) }); Desde tu codigo

Además, si está tratando de obtener una información compartida para que esté disponible a través de diferentes controladores, existe otra forma de lograrlo, y es servicios angulares. Dado que los servicios son singletons, la información se puede almacenar y buscar entre los controladores. Simplemente cree y obtenga Las funciones de establecimiento en ese servicio, exponen estas funciones, crean variables globales en el servicio y las utilizan para almacenar la información.


El (los) alcance (s) se puede usar para propagar, enviar un evento al alcance hijo o padre.

$ emit - propaga el evento al padre. $ broadcast - propaga el evento a los niños. $ on - método para escuchar los eventos, propagado por $ emit y $ broadcast.

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

ejemplo app.js :

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

Aquí puede probar el código: http://jsfiddle.net/zp6v0rut/41/


El siguiente código muestra los dos sub-controladores desde donde los eventos se envían hacia arriba al controlador principal (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/


Esta es mi función:

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

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

La forma más fácil :

HTML

  <div ng-app="myApp" ng-controller="myCtrl"> 

        <button ng-click="sendData();"> Send Data </button>

    </div>

JavaScript

    <script>
        var app = angular.module('myApp', []);
        app.controller('myCtrl', function($scope, $rootScope) {
            function sendData($scope) {
                var arrayData = ['sam','rumona','cubby'];
                $rootScope.$emit('someEvent', arrayData);
            }

        });
        app.controller('yourCtrl', function($scope, $rootScope) {
            $rootScope.$on('someEvent', function(event, data) {
                console.log(data); 
            }); 
        });
    </script>

Puede llamar a un servicio desde su controlador que devuelve una promesa y luego utilizarlo en su controlador. Y además use $emit o $broadcast para informar a otros controladores al respecto. En mi caso, tuve que hacer llamadas http a través de mi servicio, así que hice algo como esto:

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

y mi servicio se ve asi

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

        }

    }])

También sugeriría una cuarta opción como una mejor alternativa a las opciones propuestas por @zbynour.

Use $rootScope.$emit lugar de $rootScope.$broadcast independientemente de la relación entre el transmisor y el controlador receptor. De esa manera, el evento permanece dentro del conjunto de $rootScope.$$listeners mientras que con $rootScope.$broadcast el evento se propaga a todos los ámbitos secundarios, la mayoría de los cuales probablemente no serán escuchas de ese evento de todos modos. Y, por supuesto, en el extremo del controlador que recibe, simplemente usa $rootScope.$on .

Para esta opción, debe recordar destruir los escuchas de rootScope del controlador:

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

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