Como posso enviar meu $scope
objeto de um controlador para outro usando .$emit
e .$on
métodos?
function firstCtrl($scope) {
$scope.$emit('someEvent', [1,2,3]);
}
function secondCtrl($scope) {
$scope.$on('someEvent', function(mass) { console.log(mass); });
}
Não funciona da maneira que eu acho que deveria. Como $emit
e $on
trabalhar?
javascript
angularjs
Paul Kononenko
fonte
fonte
$rootScope
para transmissão / emissão quando puder ser evitado.Respostas:
Antes de tudo, a relação de escopo pai-filho é importante. Você tem duas possibilidades para emitir algum evento:
$broadcast
- envia o evento para baixo para todos os escopos filho,$emit
- despacha o evento para cima através da hierarquia de escopo.Não sei nada sobre a relação dos seus controladores (escopos), mas existem várias opções:
Se âmbito da
firstCtrl
é pai dosecondCtrl
escopo, seu código deve funcionar, substituindo$emit
por$broadcast
emfirstCtrl
:Caso não exista relação pai-filho entre seus escopos, você pode injetar
$rootScope
no controlador e transmitir o evento para todos os escopos filhos (ou seja, tambémsecondCtrl
).Finalmente, quando você precisar despachar o evento do controlador filho para os escopos para cima, poderá usar
$scope.$emit
. Se o escopo defirstCtrl
for pai dosecondCtrl
escopo:fonte
$rootScope
em seu serviço e transmitir o evento a partir do serviço.$rootScope
- mas eu quero saber que, se eu emitir um evento de um serviço (desativado$rootScope
), o evento ainda passará para$rootScope
; PORQUE, se$broadcast
percorrer a hierarquia para baixo e$emit
percorrer PARA CIMA - o que acontece ENTRE "PARA CIMA" e "PARA BAIXO" -, pois o emissor / emissor também é o ouvinte (?). E se eu quiser que o evento seja silencioso para TODOS os escopos "PARA CIMA" e "TODO PARA BAIXO", mas seja apenas "audível" no mesmo nível do expedidor?Além disso, eu sugeriria uma quarta opção como uma alternativa melhor às opções propostas pelo @zbynour.
Use em
$rootScope.$emit
vez de$rootScope.$broadcast
independentemente da relação entre a transmissão e o controlador de recebimento. Dessa forma, o evento permanece dentro do conjunto$rootScope.$$listeners
enquanto que$rootScope.$broadcast
o evento se propaga a todos os escopos filhos, a maioria dos quais provavelmente não serão ouvintes desse evento. E, claro, no final do controlador receptor, você apenas usa$rootScope.$on
.Para esta opção, lembre-se de destruir os ouvintes rootScope do controlador:
fonte
$rootScope
injeção nos controladores (o que geralmente não é necessário). Mas certamente outra opção, thx!Você pode enviar qualquer objeto que desejar dentro da hierarquia do seu aplicativo, incluindo $ scope .
Aqui está uma idéia rápida sobre como a transmissão e a emissão funcionam.
Observe os nós abaixo; tudo aninhado no nó 3. Você usa broadcast e emite quando possui esse cenário.
Nota: O número de cada nó neste exemplo é arbitrário; poderia facilmente ser o número um; o número dois; ou até o número 1.348. Cada número é apenas um identificador para este exemplo. O objetivo deste exemplo é mostrar o aninhamento de controladores / diretivas angulares.
Confira esta árvore. Como você responde às seguintes perguntas?
Nota: Existem outras maneiras de responder a essas perguntas, mas aqui discutiremos transmissão e emissão . Além disso, ao ler o texto abaixo, assuma que cada número tem seu próprio arquivo (diretiva, controlador) ex one.js, two.js, three.js.
Como o nó 1 fala com o nó 3 ?
No arquivo one.js
No arquivo three.js - o nó superior de todos os nós filhos necessários para se comunicar.
Como o nó 2 fala com o nó 3?
No arquivo two.js
No arquivo three.js - o nó superior de todos os nós filhos necessários para se comunicar.
Como o nó 3 fala com o nó 1 e / ou o nó 2?
No arquivo three.js - o nó superior de todos os nós filhos necessários para se comunicar.
No arquivo one.js && two.js, qualquer arquivo que você deseja capturar a mensagem ou ambos.
Como o nó 2 fala com o nó 1?
No arquivo two.js
No arquivo three.js - o nó superior de todos os nós filhos necessários para se comunicar.
No arquivo one.js
CONTUDO
Aqui está o que eu gosto de fazer.
No NÚMERO DE PAI mais alto ( 3 neste caso ...), que pode ser seu controlador pai ...
Então, no arquivo three.js
Agora, em qualquer um dos nós filhos, você só precisa emitir a mensagem $ ou capturá-la usando $ on .
NOTA: Normalmente, é bastante fácil cruzar a conversa em um caminho aninhado sem usar $ emit , $ broadcast ou $ on , o que significa que a maioria dos casos de uso é para quando você está tentando fazer o nó 1 se comunicar com o nó 2 ou vice-versa.
Como o nó 2 fala com o nó 1?
No arquivo two.js
No arquivo three.js - o nó superior de todos os nós filhos necessários para se comunicar.
Já lidamos com este, lembra?
No arquivo one.js
Você ainda precisará usar $ on com cada valor específico que deseja capturar, mas agora pode criar o que quiser em qualquer um dos nós sem ter que se preocupar em como transmitir a mensagem através da lacuna do nó pai à medida que capturamos e transmitimos o pushChangesToAllNodes genérico .
Espero que isto ajude...
fonte
The event life cycle starts at the scope on which $broadcast was called. All listeners listening for name event on this scope get notified.
portanto, você (como eu) obterá um loop infinito se implementar ctrl1 falando com ctrl2 com$on('x', function(e, data) { $broadcast('x', data) })
em ctrl3. Você precisará dessas linhas antes de transmitir;if (e.targetScope.$id === $scope.$id) { return; }
Para enviar
$scope object
de um controlador para outro, discutirei sobre$rootScope.$broadcast
e$rootScope.$emit
aqui como eles são mais utilizados.Caso 1 :
$ rootScope. $ broadcast: -
$rootScope
ouvinte não são destruídos automaticamente. Você precisa destruí-lo usando$destroy
. É melhor usar$scope.$on
como os ouvintes$scope
são destruídos automaticamente, ou seja, assim que $ scope for destruído.Ou,
Caso 2:
$ rootScope. $ emitem:
A principal diferença em $ emit e $ broadcast é que o evento $ rootScope. $ Emit deve ser escutado usando $ rootScope. $ On, porque o evento emitido nunca desce pela árvore do escopo. .
Nesse caso, você também deve destruir o ouvinte, como no caso de $ broadcast.
Editar:
Edição 2 :
fonte
Você deve usar $ rootScope para enviar e capturar eventos entre controladores no mesmo aplicativo. Injete a dependência de $ rootScope nos seus controladores. Aqui está um exemplo de trabalho.
Eventos vinculados ao objeto $ scope apenas funcionam no controlador do proprietário. A comunicação entre controladores é feita via $ rootScope ou Services.
fonte
Você pode chamar um serviço do seu controlador que retorne uma promessa e usá-lo no seu controlador. E use ainda mais
$emit
ou$broadcast
para informar outros controladores sobre isso. No meu caso, eu tive que fazer chamadas http através do meu serviço, então fiz algo assim:e meu serviço fica assim
fonte
Esta é a minha função:
fonte
fonte
O (s) escopo (s) pode ser usado para propagar, despachar evento para o escopo filho ou pai.
$ emit - propaga o evento para o pai. $ broadcast - propaga o evento para crianças. $ on - método para escutar os eventos, propagados por $ emit e $ broadcast.
exemplo index.html :
exemplo app.js :
Aqui você pode testar o código: http://jsfiddle.net/zp6v0rut/41/
fonte
O código abaixo mostra os dois subcontroladores de onde os eventos são despachados para o controlador pai (rootScope)
http://jsfiddle.net/shushanthp/zp6v0rut/
fonte
De acordo com a documentação do evento angularjs, o terminal receptor deve conter argumentos com uma estrutura como
@params
- Evento {Object} sendo o objeto de evento que contém informações sobre o evento
- {Objetos} args que são passados pelo receptor (observe que esse pode ser apenas um melhor para enviar sempre um objeto de dicionário)
$scope.$on('fooEvent', function (event, args) { console.log(args) });
Do seu códigoAlém disso, se você estiver tentando obter uma informação compartilhada disponível em diferentes controladores, existe uma outra maneira de conseguir isso e que são serviços angulares.Como os serviços são singletons, as informações podem ser armazenadas e buscadas nos controladores. O setter funciona nesse serviço, expõe essas funções, cria variáveis globais no serviço e as utiliza para armazenar as informações
fonte
O jeito mais fácil :
fonte