¿Cómo puedo enviar mi $scope
objeto de un controlador a otro usando .$emit
y .$on
métodos?
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 hacer $emit
y $on
trabajar?
javascript
angularjs
Paul Kononenko
fuente
fuente
$rootScope
para transmitir / emitir cuando se pueda evitar.Respuestas:
En primer lugar, la relación de alcance padre-hijo sí importa. Tienes dos posibilidades para emitir algún evento:
$broadcast
- envía el evento hacia abajo a todos los ámbitos secundarios,$emit
- despacha el evento hacia arriba a través de la jerarquía de alcance.No sé nada sobre la relación de sus controladores (ámbitos), pero hay varias opciones:
Si el alcance de
firstCtrl
es padre delsecondCtrl
alcance, su código debería funcionar reemplazando$emit
por$broadcast
enfirstCtrl
:En caso de que no haya una relación padre-hijo entre sus ámbitos, puede inyectar
$rootScope
en el controlador y transmitir el evento a todos los ámbitos secundarios (es decir, tambiénsecondCtrl
).Finalmente, cuando necesite enviar el evento desde el controlador secundario a ámbitos hacia arriba, puede usarlo
$scope.$emit
. Si el alcance defirstCtrl
es padre delsecondCtrl
alcance:fuente
$rootScope
en su servicio y transmitir el evento desde el servicio.$rootScope
, pero quiero saber que si emito un evento desde un servicio (fuera de$rootScope
), el evento aún se filtrará$rootScope
; PORQUE, si se$broadcast
filtra hacia ABAJO la jerarquía, y se$emit
filtra hacia ARRIBA, ¿qué sucede ENTRE "ARRIBA" y "ABAJO"? Ya que el emisor / emisor también es el oyente (?). ¿Qué sucede si deseo que el evento sea silencioso para TODOS los ámbitos "HACIA ARRIBA" y TODOS "HACIA ABAJO", pero solo sea "audible" en el mismo nivel que el despachador?Además, sugeriría una cuarta opción como una mejor alternativa a las opciones propuestas por @zbynour.
Use en
$rootScope.$emit
lugar de$rootScope.$broadcast
independientemente de la relación entre la transmisión y el controlador de recepción. 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 oyentes de ese evento de todos modos. Y, por supuesto, al final del controlador receptor solo se usa$rootScope.$on
.Para esta opción, debe recordar destruir los oyentes rootScope del controlador:
fuente
$rootScope
inyección en los controladores (lo que no se necesita en general). Pero seguramente otra opción, gracias!Puede enviar cualquier objeto que desee dentro de la jerarquía de su aplicación, incluido $ scope .
He aquí una idea rápida de cómo difusión y emiten trabajo.
Observe los nodos a continuación; todos anidados dentro del nodo 3. Usas broadcast y emites cuando tienes este escenario.
Nota: El número de cada nodo en este ejemplo es arbitrario; fácilmente podría ser el número uno; el numero dos; o incluso el número 1,348. Cada número es solo un identificador para este ejemplo. El objetivo de este ejemplo es mostrar el anidamiento de controladores / directivas angulares.
Mira este árbol ¿Cómo responde las siguientes preguntas?
Nota: Hay otras maneras de responder a estas preguntas, pero aquí vamos a discutir emisión y emiten . Además, cuando lea el texto a continuación, 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
En el archivo three.js : el nodo superior para todos los nodos secundarios necesarios para comunicarse.
¿Cómo habla el nodo 2 al nodo 3?
En el archivo two.js
En el archivo three.js : el nodo superior para todos los nodos secundarios necesarios para comunicarse.
¿Cómo habla el nodo 3 al nodo 1 y / o al nodo 2?
En el archivo three.js : el nodo superior para todos los nodos secundarios necesarios para comunicarse.
En el archivo one.js && two.js, el archivo que desee capturar el mensaje o ambos.
¿Cómo habla el nodo 2 al nodo 1?
En el archivo two.js
En el archivo three.js : el nodo superior para todos los nodos secundarios necesarios para comunicarse.
En el archivo one.js
SIN EMBARGO
Esto es lo que me gusta hacer.
En el NODO DE PADRES superior ( 3 en este caso ...), que puede ser su controlador principal ...
Entonces, en el archivo three.js
Ahora en cualquiera de los nodos secundarios solo necesita $ emitir el mensaje o atraparlo usando $ on .
NOTA: Normalmente es bastante fácil cruzar la conversación en una ruta anidada sin usar $ emit , $ broadcast o $ on , lo que significa que la mayoría de los casos de uso son 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
En el archivo three.js : el nodo superior para todos los nodos secundarios necesarios para comunicarse.
Ya manejamos este, ¿recuerdas?
En el archivo one.js
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 por cómo transmitir el mensaje a través del espacio del nodo principal a medida que capturamos y transmitimos el genérico pushChangesToAllNodes .
Espero que esto ayude...
fuente
The event life cycle starts at the scope on which $broadcast was called. All listeners listening for name event on this scope get notified.
por lo tanto, usted (como yo) obtendrá un bucle infinito si implementa ctrl1 hablando con ctrl2 con$on('x', function(e, data) { $broadcast('x', data) })
ctrl3. Necesitará estas líneas antes de transmitir;if (e.targetScope.$id === $scope.$id) { return; }
Para enviar
$scope object
de un controlador a otro, hablaré sobre$rootScope.$broadcast
y$rootScope.$emit
aquí, ya que se usan más.Caso 1 :
$ rootScope. $ broadcast: -
$rootScope
El oyente no se destruye automáticamente. Necesitas destruirlo usando$destroy
. Es mejor usarlo$scope.$on
ya que los oyentes$scope
se destruyen automáticamente, es decir, tan pronto como se destruye $ scope.O,
Caso 2:
$ rootScope. $ emit:
La principal diferencia en $ emit y $ broadcast es que el evento $ rootScope. $ Emit debe escucharse usando $ rootScope. $ On, porque el evento emitido nunca desciende por el árbol de alcance. .
En este caso también debes destruir al oyente como en el caso de $ broadcast.
Editar:
Edición 2 :
fuente
Debe usar $ rootScope para enviar y capturar eventos entre controladores en la misma aplicación. Inyecte la dependencia de $ rootScope a sus controladores. Aquí hay un ejemplo de trabajo.
Los eventos vinculados al objeto $ scope solo funcionan en el controlador propietario. La comunicación entre los controladores se realiza a través de $ rootScope o Services.
fuente
Puede llamar a un servicio desde su controlador que le devuelve una promesa y luego usarlo en su controlador. Y más uso
$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:y mi servicio se ve así
fuente
Esta es mi función:
fuente
fuente
El (los) alcance (s) se pueden usar para propagar, enviar eventos al ámbito secundario o primario.
$ emit : propaga el evento a padre. $ broadcast : propaga el evento a los niños. $ en : método para escuchar los eventos, propagado por $ emit y $ broadcast.
ejemplo index.html :
ejemplo app.js :
Aquí puede probar el código: http://jsfiddle.net/zp6v0rut/41/
fuente
El siguiente código muestra los dos subcontroladores desde donde los eventos se envían hacia arriba al controlador principal (rootScope)
http://jsfiddle.net/shushanthp/zp6v0rut/
fuente
De acuerdo con los documentos del evento angularjs, el extremo receptor debería contener argumentos con una estructura como
@params
- El evento {Object} es el objeto del evento que contiene información sobre el evento
- Argumentos {Objeto} que pasa la persona que llama (Tenga en cuenta que esto solo puede ser uno mejor para enviar siempre un objeto de diccionario)
$scope.$on('fooEvent', function (event, args) { console.log(args) });
De su códigoAdemás, si está tratando de obtener una información compartida para que esté disponible en diferentes controladores, hay otra forma de lograrlo y son los servicios angulares. Dado que los servicios son únicos, la información se puede almacenar y buscar en los controladores. Simplemente cree getter y establece funciones en ese servicio, expone estas funciones, crea variables globales en el servicio y las usa para almacenar la información
fuente
La forma más fácil :
fuente