Dlaczego używamy $ rootScope. $ Broadcast w AngularJS?

109

Próbowałem znaleźć podstawowe informacje o AngularJS $rootScope.$broadcast, ale dokumentacja AngularJS niewiele pomaga. W prostych słowach, dlaczego tego używamy?

Ponadto w szablonie Hot Towel Johna Papy znajduje się niestandardowa funkcja we wspólnym module o nazwie $broadcast:

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

Nie rozumiem, co to robi. Oto kilka podstawowych pytań:

1) Co robi $rootScope.$broadcast?

2) Jaka jest różnica między $rootScope.$broadcasti $rootScope.$broadcast.apply?

Nexus23
źródło
$rootScope.$broadcast.apply()jest używany, ponieważ jeśli chcesz przekazać specjalny argumentsobiekt do innej funkcji, musisz go użyć apply()(w przeciwieństwie do call()). Oprócz linku @ Blackhole do strony MDN w aplikacji, możesz również sprawdzić wpis na arguments.
Scott Schupbach

Odpowiedzi:

97
  1. Co robi $rootScope.$broadcast?

    $rootScope.$broadcastwysyła zdarzenie za pośrednictwem zakresu aplikacji. Wszelkie dzieci zakres tej aplikacji można złapać go za pomocą prostego: $scope.$on().

    Jest to szczególnie przydatne do wysyłania zdarzeń, gdy chcesz dotrzeć do zakresu, który nie jest bezpośrednim rodzicem (na przykład gałąź rodzica)

    !!! Jedną rzeczą, której nie należy robić, jest jednak korzystanie $rootScope.$onz kontrolera. $rootScopejest aplikacją, kiedy twój kontroler zostanie zniszczony, ten detektor zdarzeń będzie nadal istniał, a kiedy twój kontroler zostanie utworzony ponownie, po prostu zgromadzi więcej detektorów zdarzeń. (Tak więc jedna transmisja zostanie przechwycona wiele razy). Użyj $scope.$on()zamiast tego, a słuchacze również zostaną zniszczeni.

  2. Jaka jest różnica między $rootScope.$broadcast& $rootScope.$broadcast.apply?

    Czasami trzeba go używać apply(), zwłaszcza podczas pracy z dyrektywami i innymi bibliotekami JS. Jednak ponieważ nie znam tej bazy kodu, nie byłbym w stanie powiedzieć, czy tak jest w tym przypadku.

user1412031
źródło
11
Świetny chwyt na $rootScope.$onwycieku pamięci. Dotyczy to również zaakceptowanej odpowiedzi, ponieważ kontrolerzy prawdopodobnie będą wywoływać hiEventServiceutworzoną przez siebie odpowiedź.
adamdport
Jaki jest przykład, w którym $broadcast$broadcast.apply()
gość
$ rootScope. $ broadcast wysyła zdarzenie do wszystkich słuchaczy, nie tylko do słuchaczy z zakresów podrzędnych. $ scope. $ broadcast ogranicza wydarzenie do zakresów podrzędnych
Geert Bellemans
157

$rootScope zasadniczo działa jako detektor i dyspozytor zdarzeń.

Aby odpowiedzieć na pytanie, jak jest używany, używamy go w połączeniu z rootScope.$on;

$rootScope.$broadcast("hi");

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

Jednak używanie $rootScopejako ogólnej usługi zdarzeń własnej aplikacji jest złą praktyką , ponieważ szybko znajdziesz się w sytuacji, w której każda aplikacja zależy od $ rootScope i nie wiesz, jakie komponenty nasłuchują jakich zdarzeń.

Najlepszą praktyką jest utworzenie usługi dla każdego wydarzenia niestandardowego, którego chcesz słuchać lub transmitować.

.service("hiEventService",function($rootScope) {
    this.broadcast = function() {$rootScope.$broadcast("hi")}
    this.listen = function(callback) {$rootScope.$on("hi",callback)}
})
Zaklinacz kodów
źródło
4
Dzięki @itcouldevenbeabout, czy ta linia nie wywołuje tej samej logiki dołączania zdarzenia do globalnego $ rootScope? function () {$ rootScope. $ broadcast ("hi")}, o której wspomniałeś jest złą praktyką?
Nexus
11
Korzystanie z usługi w celu nadawania transmisji, a także dołączania słuchaczy do określonego wydarzenia pozwala uniknąć sytuacji, w której nie masz pewności, kto słucha. Staje się jasne, które komponenty mają usługę zdarzeń jako zależność
CoolTapes
4
Po odkryciu różnicy między $ emit a $ broadcast, byłbym skłonny powiedzieć, że lepiej byłoby $ emitować zdarzenie - w ten sposób zdarzenie zanieczyszcza się w możliwie najmniejszym zestawie zakresów (najlepiej, gdyby usługa miała to własny zakres, ale nie sądzę, żeby to było możliwe?)
Brondahl
3
-1. Nie rozumiem, jak izolacja w usłudze jest lepsza niż zwykłe nadawanie. W każdym razie lepiej użyj własnego prywatnego zakresu w usłudze. I lepiej używaj $ emit, a nie $ broadcast. Również proponowana usługa nie obsługuje argumentów zdarzeń. Co gorsza, nie obsługuje rezygnacji z subskrypcji; grzech śmiertelny dla $ rootScope.
alpha-mouse
3
Brak wypisania rujnuje dla mnie tę odpowiedź. Jeśli wywołujesz hiEventService.listen(callback)z kontrolera, słuchacz będzie nadal istniał nawet po zniszczeniu kontrolera. Wyciek pamięci! Powiązanie z zakresem kontrolera $scope.$on("hi",callback)obejmuje automatyczne czyszczenie.
adamdport
32

$ rootScope. $ broadcast to wygodny sposób na wywołanie zdarzenia „globalnego”, którego mogą nasłuchiwać wszystkie zasięgi potomne. Musisz użyć tylko $rootScopedo rozgłaszania wiadomości, ponieważ wszystkie zakresy podrzędne mogą go nasłuchiwać.

Zakres główny rozgłasza zdarzenie:

$rootScope.$broadcast("myEvent");

Każde dziecko Scope może nasłuchiwać zdarzenia:

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

Dlaczego używamy $ rootScope. $ Broadcast? Możesz użyć $watchdo nasłuchiwania zmian zmiennych i wykonywania funkcji, gdy zmienia się stan zmiennej. Jednak w niektórych przypadkach po prostu chcesz zgłosić zdarzenie, którego mogą nasłuchiwać inne części aplikacji, niezależnie od jakiejkolwiek zmiany stanu zmiennej zakresu. Wtedy jest $broadcastto pomocne.

James Lawruk
źródło
19

Przekazywanie danych !!!

Zastanawiam się, dlaczego nikt nie wspomniał, że $broadcastakceptują parametr, w którym można przekazać, Objectktóry zostanie odebrany za $onpomocą funkcji zwrotnej

Przykład:

// 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
})
Merlinie
źródło
8

Co robi $ rootScope. $ Broadcast?

Rozgłasza wiadomość do odpowiednich słuchaczy w całej aplikacji kątowej, bardzo potężny środek do przesyłania wiadomości do zakresów na różnych poziomach hierarchii (czy to rodzic, dziecko czy rodzeństwo)

Podobnie, mamy $ rootScope. $ Emit, jedyną różnicą jest to, że pierwsza jest również przechwytywana przez $ scope. $ On, podczas gdy druga jest przechwytywana tylko przez $ rootScope. $ On.

zobacz przykłady: - http://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/

Prashant K.
źródło