Por que usamos $ rootScope. $ Broadcast em AngularJS?

109

Tentei encontrar algumas informações básicas para AngularJS $rootScope.$broadcast, mas a documentação do AngularJS não ajuda muito. Em palavras fáceis, por que usamos isso?

Além disso, dentro do modelo Hot Towel de John Papa, há uma função personalizada no módulo comum chamada $broadcast:

function $broadcast() {
    return $rootScope.$broadcast.apply($rootScope, arguments);
}

Eu não entendi o que isso está fazendo. Então, aqui estão algumas perguntas básicas:

1) O que $rootScope.$broadcastfazer?

2) Qual é a diferença entre $rootScope.$broadcaste $rootScope.$broadcast.apply?

Nexus23
fonte
$rootScope.$broadcast.apply()é usado porque se você deseja passar o argumentsobjeto especial para outra função, você precisa usar apply()(ao invés de call()). Além do link de @ Blackhole para a página MDN em aplicar, você também pode verificar a entrada em arguments.
Scott Schupbach,

Respostas:

97
  1. O que $rootScope.$broadcastfazer?

    $rootScope.$broadcastestá enviando um evento por meio do escopo do aplicativo. Qualquer criança alcance desse aplicativo pode pegá-lo usando um simples: $scope.$on().

    É especialmente útil enviar eventos quando você deseja alcançar um escopo que não seja um pai direto (um ramo de um pai, por exemplo)

    !!! Uma coisa a não fazer, no entanto, é usar a $rootScope.$onpartir de um controlador. $rootScopeé a aplicação, quando seu controlador for destruído, aquele ouvinte de evento ainda existirá, e quando seu controlador for criado novamente, ele apenas acumulará mais ouvintes de evento. (Assim, uma transmissão será capturada várias vezes). Em $scope.$on()vez disso, use e os ouvintes também serão destruídos.

  2. Qual é a diferença entre $rootScope.$broadcast& $rootScope.$broadcast.apply?

    Às vezes você precisa usar apply(), especialmente ao trabalhar com diretivas e outras bibliotecas JS. No entanto, como não conheço essa base de código, não seria capaz de dizer se é esse o caso aqui.

user1412031
fonte
11
Grande pegada no $rootScope.$onvazamento de memória. Isso também se aplica à resposta aceita, pois os controladores provavelmente chamarão o hiEventServicecriado.
adamdport
Qual é um exemplo em que você usaria $broadcastvs.$broadcast.apply()
convidado de
$ rootScope. $ broadcast envia o evento para todos os ouvintes, não apenas ouvintes de escopos filhos. $ scope. $ broadcast limita o evento a escopos filhos
Geert Bellemans,
157

$rootScope basicamente funciona como um ouvinte e despachante de eventos.

Para responder à questão de como ele é usado, é usado em conjunto com rootScope.$on;

$rootScope.$broadcast("hi");

$rootScope.$on("hi", function(){
    //do something
});

No entanto, é uma prática ruim usar $rootScopecomo serviço de evento geral do seu próprio aplicativo, já que você rapidamente terminará em uma situação em que cada aplicativo depende de $ rootScope e você não sabe quais componentes estão ouvindo quais eventos.

A prática recomendada é criar um serviço para cada evento personalizado que você deseja ouvir ou transmitir.

.service("hiEventService",function($rootScope) {
    this.broadcast = function() {$rootScope.$broadcast("hi")}
    this.listen = function(callback) {$rootScope.$on("hi",callback)}
})
Codigo Whisperer
fonte
4
Obrigado @itcouldevenbeabout não é esta linha chamando a mesma lógica de anexar um evento ao global $ rootScope? function () {$ rootScope. $ broadcast ("hi")}, que você mencionou é uma prática ruim?
Nexus23 de
11
Usar um serviço para fazer as transmissões e também anexar os ouvintes de um evento específico evita a situação em que você não tem certeza de quem está ouvindo. Torna-se claro quais componentes têm o serviço de evento como uma dependência
CoolTapes
4
Tendo acabado de descobrir a diferença entre $ emit e $ broadcast, estaria inclinado a dizer que seria melhor $ emitir o evento - dessa forma, você poluindo o evento no menor conjunto possível de escopos (idealmente, o serviço teria é seu próprio escopo, mas eu não acho que isso seja possível?)
Brondahl
3
-1. Não vejo como o isolamento em um serviço é melhor do que simplesmente transmitir. Enfim, é melhor usar escopo privado próprio no serviço. E é melhor usar $ emit, e não $ broadcast. Além disso, o serviço proposto não oferece suporte a argumentos de evento. O que é pior, não oferece suporte para cancelamento de assinatura; um pecado mortal para $ rootScope.
alpha-mouse
3
A falta de cancelamento de assinatura estraga esta resposta para mim. Se você chamar hiEventService.listen(callback)de um controlador, o ouvinte ainda existirá mesmo depois que o controlador for destruído. Vazamento de memória! A vinculação ao escopo do controlador $scope.$on("hi",callback)vem com limpeza automática.
adamdport
32

$ rootScope. $ broadcast é uma maneira conveniente de gerar um evento "global" que todos os escopos filhos podem ouvir. Você só precisa usar $rootScopepara transmitir a mensagem, já que todos os escopos descendentes podem ouvi-la.

O escopo raiz transmite o evento:

$rootScope.$broadcast("myEvent");

Qualquer filho Scope pode ouvir o evento:

$scope.$on("myEvent",function () {console.log('my event occurred');} );

Por que usamos $ rootScope. $ Broadcast? Você pode usar $watchpara ouvir as mudanças de variáveis ​​e executar funções quando o estado da variável muda. No entanto, em alguns casos, você simplesmente deseja gerar um evento que outras partes do aplicativo possam ouvir, independentemente de qualquer alteração no estado da variável de escopo. É quando $broadcasté útil.

James Lawruk
fonte
19

Passando dados !!!

Eu me pergunto por que ninguém menciona que $broadcastaceita um parâmetro onde você pode passar um Objectque será recebido $onusando uma função de callback

Exemplo:

// the object to transfert
var myObject = {
    status : 10
}

$rootScope.$broadcast('status_updated', myObject);
$scope.$on('status_updated', function(event, obj){
    console.log(obj.status); // 10
})
Merlin
fonte
8

O que $ rootScope. $ Broadcast faz?

Ele transmite a mensagem para os respectivos ouvintes em todo o aplicativo angular, um meio muito poderoso de transferir mensagens para escopos em diferentes níveis hierárquicos (seja pai, filho ou irmãos)

Da mesma forma, temos $ rootScope. $ Emit, a única diferença é que o primeiro também é capturado por $ scope. $ On, enquanto o último é capturado apenas por $ rootScope. $ On.

consulte para exemplos: - http://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/

Prashant K
fonte