$rootScope.$ широковещание против $scope.$emit
Теперь, когда разница в производительности между $broadcast
а также $emit
был устранен, есть ли причина предпочитать $scope.$emit
в $rootScope.$broadcast
?
Они разные, да.
$emit
ограничено иерархией области действия (вверх) - это может быть хорошо, если оно соответствует вашему дизайну, но мне кажется, это довольно произвольное ограничение.
$rootScope.$broadcast
работает во всех, кто хочет слушать событие, что является более разумным ограничением в моем уме.
Я что-то пропустил?
РЕДАКТИРОВАТЬ:
Чтобы уточнить в ответ на ответ, направление отправки не вопрос, который я после. $scope.$emit
отправляет событие вверх, и $scope.$broadcast
- вниз. Но почему бы не всегда использовать $rootScope.$broadcast
достичь всех предполагаемых слушателей?
6 ответов
tl;dr (это tl;dr из ответа @sp00m ниже)
$emit
отправляет событие вверх...$broadcast
отправляет событие вниз
Детальное объяснение
$rootScope.$emit
только позволяет другим $rootScope
слушатели ловят это. Это хорошо, когда ты не хочешь каждый $scope
чтобы получить это. В основном общение высокого уровня. Думайте об этом как о взрослых, разговаривающих друг с другом в комнате, чтобы дети не могли их слышать.
$rootScope.$broadcast
это метод, который позволяет почти всем слышать это. Это было бы равносильно тому, что родители кричат, что ужин готов, поэтому все в доме слышат его.
$scope.$emit
когда ты этого хочешь $scope
и все его родители и $rootScope
услышать событие. Это ребенок, который ныет родителям дома (но не в продуктовом магазине, где другие дети могут слышать).
$scope.$broadcast
для $scope
себя и своих детей. Это ребенок, шепчущий своим чучелам, чтобы их родители не могли слышать.
Они не делают ту же работу: $emit
отправляет событие вверх по иерархии области, в то время как $broadcast
отправляет событие вниз во все дочерние области.
Я сделал следующий рисунок из следующей ссылки: https://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/
Как вы видете, $rootScope.$broadcast
бьет гораздо больше слушателей, чем $scope.$emit
,
Также, $scope.$emit
пузырящийся эффект можно отменить, тогда как $rootScope.$broadcast
не могу.
$scope.$emit: этот метод отправляет событие в направлении вверх (от дочернего к родительскому)
$ scope. $ broadcast: метод отправляет событие в направлении вниз (от родителя к потомку) всем дочерним контроллерам.
$ scope. $ on: метод регистрирует прослушивание какого-либо события. Все контроллеры, которые прослушивают это событие, получают уведомление о широковещании или излучении в зависимости от того, где они находятся в иерархии дочерних элементов.
Событие $ emit может быть отменено любым из $ scope, который прослушивает событие.
$ On предоставляет метод stopPropagation. При вызове этого метода событие может быть остановлено для дальнейшего распространения.
Плункер: https://embed.plnkr.co/0Pdrrtj3GEnMp2UpILp4/
В случае одноуровневых областей (областей, которые не находятся в прямой иерархии родитель-потомок), $ emit и $ broadcast не будут связываться с одноуровневыми областями.
Для получения более подробной информации, пожалуйста, обратитесь к http://yogeshtutorials.blogspot.in/2015/12/event-based-communication-between-angularjs-controllers.html
@ Эдди дал прекрасный ответ на заданный вопрос. Но я хотел бы обратить внимание на использование более эффективного подхода Pub/Sub.
Как следует из этого ответа,
Подход $broadcast/$on не очень эффективен, так как он вещает на все области (в одном или обоих направлениях иерархии Scope). Хотя подход Pub / Sub гораздо более прямой. Мероприятия получают только подписчики, поэтому не все системы будут работать.
ты можешь использовать angular-PubSub
угловой модуль. как только вы добавите PubSub
модуль зависимости вашего приложения, вы можете использовать PubSub
сервис подписки и отписки от событий / тем.
Легко подписаться:
// Subscribe to event
var sub = PubSub.subscribe('event-name', function(topic, data){
});
Легко публиковать
PubSub.publish('event-name', {
prop1: value1,
prop2: value2
});
Чтобы отписаться, используйте PubSub.unsubscribe(sub);
ИЛИ ЖЕ PubSub.unsubscribe('event-name');
,
ПРИМЕЧАНИЕ Не забудьте отписаться, чтобы избежать утечек памяти.
Используйте RxJS в Сервисе
Как насчет ситуации, когда у вас есть Служба, которая удерживает состояние, например. Как я могу отправить изменения в эту Службу и другие случайные компоненты на странице, чтобы быть в курсе таких изменений? В последнее время боролся с этой проблемой
Создайте сервис с расширениями RxJS для Angular.
<script src="//unpkg.com/angular/angular.js"></script>
<script src="//unpkg.com/rx/dist/rx.all.js"></script>
<script src="//unpkg.com/rx-angular/dist/rx.angular.js"></script>
var app = angular.module('myApp', ['rx']);
app.factory("DataService", function(rx) {
var subject = new rx.Subject();
var data = "Initial";
return {
set: function set(d){
data = d;
subject.onNext(d);
},
get: function get() {
return data;
},
subscribe: function (o) {
return subject.subscribe(o);
}
};
});
Тогда просто подпишитесь на изменения.
app.controller('displayCtrl', function(DataService) {
var $ctrl = this;
$ctrl.data = DataService.get();
var subscription = DataService.subscribe(function onNext(d) {
$ctrl.data = d;
});
this.$onDestroy = function() {
subscription.dispose();
};
});
Клиенты могут подписаться на изменения с DataService.subscribe
и производители могут продвигать изменения с DataService.set
,