Perché usiamo $ rootScope. $ Broadcast in AngularJS?


109

Ho provato a trovare alcune informazioni di base per AngularJS $rootScope.$broadcast, ma la documentazione di AngularJS non aiuta molto. In parole semplici, perché lo usiamo?

Inoltre, all'interno del modello Hot Towel di John Papa c'è una funzione personalizzata nel modulo comune denominata $broadcast:

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

Non ho capito cosa stia facendo. Quindi ecco un paio di domande di base:

1) Cosa fa $rootScope.$broadcast?

2) Qual è la differenza tra $rootScope.$broadcaste $rootScope.$broadcast.apply?




$rootScope.$broadcast.apply()viene utilizzato perché se vuoi passare l' argumentsoggetto speciale a un'altra funzione, devi usare apply()(al contrario di call()). Oltre al collegamento di @ Blackhole alla pagina MDN su candidatura, potresti anche controllare la voce su arguments.
Scott Schupbach

Risposte:


97
  1. Cosa fa $rootScope.$broadcast?

    $rootScope.$broadcaststa inviando un evento attraverso l'ambito dell'applicazione. Qualsiasi figli portata di tale applicazione può prenderlo con un semplice: $scope.$on().

    È particolarmente utile inviare eventi quando si desidera raggiungere un ambito che non è un genitore diretto (ad esempio un ramo di un genitore)

    !!! Una cosa da non fare tuttavia è utilizzare $rootScope.$onda un controller. $rootScopeè l'applicazione, quando il tuo controller viene distrutto, il listener di eventi esisterà ancora e quando il tuo controller verrà creato di nuovo, accumulerà semplicemente più listener di eventi. (Quindi una trasmissione verrà catturata più volte). Usa $scope.$on()invece e anche gli ascoltatori verranno distrutti.

  2. Qual'è la differenza tra $rootScope.$broadcast& $rootScope.$broadcast.apply?

    A volte devi usare apply(), specialmente quando lavori con direttive e altre librerie JS. Tuttavia, poiché non conosco quella base di codice, non sarei in grado di dire se questo è il caso qui.


11
Grande cattura sulla $rootScope.$onperdita di memoria. Questo vale anche per la risposta accettata, poiché è probabile che i controllori chiamino la che hiEventServiceha creato.
adamdport

Qual è un esempio in cui useresti $broadcastcontro$broadcast.apply()
ospite il

$ rootScope. $ broadcast invia l'evento a tutti i listener, non solo ai listener degli ambiti figli. $ scope. $ broadcast limita l'evento agli ambiti figlio
Geert Bellemans

157

$rootScope fondamentalmente funziona come listener e dispatcher di eventi.

Per rispondere alla domanda su come viene utilizzato, è usato insieme a rootScope.$on;

$rootScope.$broadcast("hi");

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

Tuttavia, è una cattiva pratica da utilizzare $rootScopecome servizio di eventi generali della propria app, poiché si finirà rapidamente in una situazione in cui ogni app dipende da $ rootScope e non si sa quali componenti stanno ascoltando quali eventi.

La best practice è creare un servizio per ogni evento personalizzato che desideri ascoltare o trasmettere.

.service("hiEventService",function($rootScope) {
    this.broadcast = function() {$rootScope.$broadcast("hi")}
    this.listen = function(callback) {$rootScope.$on("hi",callback)}
})

4
Grazie @itcouldevenbeabout questa linea non chiama la stessa logica di allegare un evento a $ rootScope globale? function () {$ rootScope. $ broadcast ("hi")}, che hai menzionato come una cattiva pratica?
Nexus23

11
Usare un servizio per fare le trasmissioni e anche allegare gli ascoltatori per un evento specifico evita la situazione in cui non sei sicuro di chi sta ascoltando. Diventa chiaro quali componenti hanno il servizio eventi come dipendenza
CoolTapes

4
Avendo appena scoperto la differenza tra $ emit e $ broadcast, sarei propenso a dire che sarebbe meglio $ emit l'evento - in questo modo l'evento inquina nel più piccolo insieme di ambiti possibile (idealmente il servizio avrebbe è proprio scopo, ma non credo sia possibile?)
Brondahl

3
-1. Non vedo come l'isolamento in un servizio sia migliore della semplice trasmissione. Comunque, meglio usare il proprio ambito privato nel servizio. E meglio usare $ emit e non $ broadcast. Inoltre, il servizio proposto non supporta gli argomenti dell'evento. Quel che è peggio, non supporta l'annullamento dell'iscrizione; un peccato mortale per $ rootScope.
alfa-topo

3
La mancanza di disiscrizione mi rovina questa risposta. Se chiami hiEventService.listen(callback)da un controller, il listener continuerà a esistere anche dopo che il controller è stato distrutto. Perdita di memoria! L'associazione all'ambito del controller $scope.$on("hi",callback)viene fornita con la pulizia automatica.
adamdport

32

$ rootScope. $ broadcast è un modo conveniente per generare un evento "globale" che tutti gli ambiti figlio possono ascoltare. È necessario solo utilizzare $rootScopeper trasmettere il messaggio, poiché tutti gli ambiti discendenti possono ascoltarlo.

L'ambito radice trasmette l'evento:

$rootScope.$broadcast("myEvent");

Qualsiasi Scope bambino può ascoltare l'evento:

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

Perché usiamo $ rootScope. $ Broadcast? È possibile utilizzare $watchper ascoltare i cambiamenti delle variabili ed eseguire funzioni quando lo stato della variabile cambia. Tuttavia, in alcuni casi, si desidera semplicemente generare un evento che altre parti dell'applicazione possono ascoltare, indipendentemente da qualsiasi cambiamento nello stato della variabile di ambito. Questo è quando $broadcastè utile.


19

Passaggio di dati !!!

Mi chiedo perché nessuno menziona che $broadcastaccetta un parametro in cui è possibile passare un messaggio Objectche verrà ricevuto $onutilizzando una funzione di callback

Esempio:

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

8

Cosa fa $ rootScope. $ Broadcast?

Trasmette il messaggio ai rispettivi ascoltatori in tutta l'app angolare, un mezzo molto potente per trasferire i messaggi in ambiti a diversi livelli gerarchici (che si tratti di genitore, figlio o fratelli)

Allo stesso modo, abbiamo $ rootScope. $ Emit, l'unica differenza è che il primo è catturato anche da $ scope. $ On mentre il secondo è catturato solo da $ rootScope. $ On.

fare riferimento per esempi: - http://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.