Agora que a diferença de desempenho entre $broadcaste $emitfoi eliminada, há alguma razão para preferir $scope.$emita $rootScope.$broadcast?
Eles são diferentes, sim.
$emit está restrito à hierarquia de escopo (para cima) - isso pode ser bom, se for adequado ao seu design, mas me parece uma restrição bastante arbitrária.
$rootScope.$broadcastfunciona em todos os que escolhem ouvir o evento, o que é uma restrição mais sensata em minha mente.
Para esclarecer em resposta a uma resposta, a direção da expedição não é o problema que estou procurando. $scope.$emitdespacha o evento para cima e $scope.$broadcastpara baixo. Mas por que não usar sempre $rootScope.$broadcastpara alcançar todos os ouvintes pretendidos?
— New Dev
toddmotto.com/… tem tudo #
— Divya MV
tl; dr (este tl; dr é da resposta de @ sp00m abaixo)
$emitdespacha um evento para cima ... $broadcastdespacha um evento para baixo
$rootScope.$emitapenas permite que outros $rootScopeouvintes o capturem. Isso é bom quando você não quer que todos $scopeobtenham. Principalmente uma comunicação de alto nível. Pense nisso como adultos conversando em uma sala para que as crianças não possam ouvi-los.
$rootScope.$broadcasté um método que permite que praticamente tudo o ouça. Isso seria o equivalente a pais gritando que o jantar está pronto para que todos na casa o ouçam.
$scope.$emité quando você quer isso $scopee todos os seus pais e $rootScopeouvir o evento. É uma criança choramingando para os pais em casa (mas não em um supermercado onde outras crianças possam ouvir).
$scope.$broadcasté para $scopesi e seus filhos. É uma criança sussurrando para seus bichos de pelúcia para que seus pais não possam ouvir.
@NewDev O motivo é que muitas vezes você tem repetição de escopos na página. Se você tiver dois ou mais escopos representando diferentes instâncias de dados - por exemplo, uma lista de registros de pacientes em uma página, cada um com seu próprio escopo -, não funcionará para transmitir da raiz um evento destinado a apenas um deles. escopos. Evitar $rootScopetransmissões sempre que possível permite uma melhor reutilização.
Nada do que você disse está errado, mas uma maneira de generalizar que $ emit diminui o documento para escopos filho e $ emit aumenta o documento para escopos pai. Ambos acionarão todos os ouvintes conectados ao escopo atual.
— 1176 Eric Eric
O exemplo que você usou é ótimo!
Uau! Até as crianças podem entender isso! :) incrível
Exemplo perfeito, amo a explicação
Eles não estão fazendo o mesmo trabalho: $emitdespacha um evento para cima através da hierarquia de escopo, enquanto $broadcastdespacha um evento para baixo para todos os escopos filhos.
Sim, observei isso na pergunta (talvez eu pudesse ter deixado claro sobre a direção da expedição). Mas também observei que essa é uma restrição bastante arbitrária. Se posso alcançar meu "ouvinte", por que não consigo sempre fazer isso de baixo para baixo $rootScope?
— Nova Dev
Porque um $ emit não afetará os escopos filho ou irmão de um escopo. Eles são mapeados apenas para os tipos de propagação de eventos do javascript - capturando e borbulhando. $ broadcast é usado para capturar e $ emit são usados ​​para borbulhar. Há um artigo quirksmode agora aparentemente antigo que explica a diferença muito bem: quirksmode.org/js/events_order.html
Criei o seguinte gráfico a partir do seguinte link: https://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/
Como você pode ver, $rootScope.$broadcastatinge muito mais ouvintes do que $scope.$emit.
Além disso, $scope.$emito efeito de bolha do pode ser cancelado, enquanto $rootScope.$broadcastnão pode.
Eu vejo muitas flechas.
@MichalStefanow Eu sou um fã de respostas visuais :)
@mparnisari:. $ broadcast (nome, args) -. Transmissão um evento para baixo através do $ âmbito de todas as crianças $ Emit (nome, args) - Emit um evento para cima na hierarquia $ âmbito a todos os pais, incluindo os US $ rootScope
$ scope. $ emit: este método despacha o evento na direção ascendente (do filho para o pai)
$ scope. $ broadcast: o método despacha o evento na direção descendente (de pai para filho) para todos os controladores filhos.
$ scope. $ on: o método é registrado para ouvir algum evento. Todos os controladores que estão ouvindo esse evento recebem uma notificação da transmissão ou emitem com base no local em que eles se encaixam na hierarquia pai-filho.
O evento $ emit pode ser cancelado por qualquer um dos escopos $ que estiver ouvindo o evento.
O $ on fornece o método "stopPropagation". Ao chamar esse método, o evento pode ser impedido de se propagar mais.
No caso de escopos irmãos (os escopos que não estão na hierarquia pai-filho direta), $ emitem e $ broadcast não se comunicam com os escopos irmãos.
Para obter mais detalhes, consulte http://yogeshtutorials.blogspot.in/2015/12/event-based-communication-between-angularjs-controllers.html
Um link para uma solução é bem-vindo, mas garanta que sua resposta seja útil sem ela: adicione contexto ao link para que seus colegas usuários tenham uma idéia do que é e por que está lá, depois cite a parte mais relevante da página que você ' reencaminhando para o caso de a página de destino estar indisponível. Respostas que são pouco mais que um link podem ser excluídas.
O objetivo era fornecer o plunker de trabalho, no entanto, adicionei a descrição apropriada aqui.
@ Eddie deu uma resposta perfeita da pergunta. Mas eu gostaria de chamar a atenção para o uso de uma abordagem mais eficiente do Pub / Sub.
Como essa resposta sugere,
A abordagem $ broadcast / $ on não é terrivelmente eficiente, pois é transmitida para todos os escopos (em uma direção ou em ambas as direções da hierarquia do escopo). Enquanto a abordagem Pub / Sub é muito mais direta. Somente os assinantes recebem os eventos; portanto, não é necessário que todos os escopos do sistema funcionem.
você pode usar angular-PubSubo módulo angular. depois de adicionar o PubSubmódulo à dependência do aplicativo, você pode usar o PubSubserviço para assinar e cancelar a inscrição de eventos / tópicos.
Fácil de se inscrever:
Para cancelar a inscrição, use PubSub.unsubscribe(sub);OR PubSub.unsubscribe('event-name');.
NOTA Não se esqueça de cancelar a inscrição para evitar vazamentos de memória.
Use RxJS em um serviço
E em uma situação em que você tem um Serviço que está mantendo o estado, por exemplo. Como eu poderia enviar alterações para esse Serviço e outros componentes aleatórios na página estar cientes dessa alteração? Ultimamente, tenho lutado para resolver esse problema
Crie um serviço com RxJS Extensions for Angular .
Em seguida, basta assinar as alterações.
Os clientes podem assinar alterações DataService.subscribee os produtores podem enviar alterações com DataService.set.