it-swarm.com.ru

$ rootScope. $ широковещание против $ scope. $ emit

Теперь, когда разница в производительности между $broadcast и $emit устранена, есть ли причина предпочесть $scope.$emit$rootScope.$broadcast?

Они разные, да.

$emit ограничен иерархией областей действия (вверх) - это может быть хорошо, если оно соответствует вашему дизайну, но мне кажется, это довольно произвольное ограничение.

$rootScope.$broadcast работает со всеми , выбирающими , чтобы прослушать событие, что является более разумным ограничением в моем уме.

Я что-то пропустил?

EDIT:

Чтобы уточнить в ответ на ответ, направление отправки не вопрос, который я после. $scope.$emit отправляет событие вверх, а $scope.$broadcast - вниз. Но почему бы не всегда использовать $rootScope.$broadcast для охвата всех предполагаемых слушателей?

344
New Dev

tl; dr (этот tl; dr из @ sp00m ответа ниже)

$emit отправляет событие вверх ... $broadcast отправляет событие вниз

Подробное объяснение

$rootScope.$emit позволяет только другим $rootScope слушателям ловить его. Это хорошо, когда вы не хотите, чтобы каждый $scope получал его. В основном общение высокого уровня. Думайте об этом как о взрослых, разговаривающих друг с другом в комнате, чтобы дети не могли их слышать.

$rootScope.$broadcast - это метод, который позволяет почти всем слышать это. Это было бы равносильно тому, что родители кричат, что ужин готов, поэтому все в доме его слышат.

$scope.$emit - это когда вы хотите, чтобы $scope и все его родители и $rootScope услышали событие. Это ребенок, который ныет родителям дома (но не в продуктовом магазине, где другие дети могут слышать).

$scope.$broadcast предназначен для самого $scope и его дочерних элементов. Это ребенок шепчет своим чучелам, чтобы их родители не могли слышать.

1136
Eddie Monge Jr

Они не выполняют ту же работу: $emit отправляет событие вверх через иерархию области действия, в то время как $broadcast отправляет событие вниз во все дочерние области.

103
sp00m

Я сделал следующий рисунок из следующей ссылки: https://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribeing/

Scope, rootScope, emit, broadcast

Как видите, $rootScope.$broadcast привлекает гораздо больше слушателей, чем $scope.$emit.

Кроме того, эффект $scope.$emitbubling можно отменить, тогда как $rootScope.$broadcast нельзя.

76
Maria Ines Parnisari

enter image description here

$ scope. $ emit: этот метод отправляет событие в направлении вверх (от дочернего к родительскому)

enter image description here $ scope. $ broadcast: метод отправляет событие в направлении вниз (от родителя к потомку) всем дочерним контроллерам.

enter image description here $ scope. $ on: метод регистрируется для прослушивания какого-либо события. Все контроллеры, которые прослушивают это событие, получают уведомление о широковещании или излучении в зависимости от того, где они находятся в иерархии дочерних элементов.

Событие $ emit может быть отменено любым из $ scope, который прослушивает событие.

$ On предоставляет метод stopPropagation. При вызове этого метода событие может быть остановлено для дальнейшего распространения.

Плункер: https://embed.plnkr.co/0Pdrrtj3GEnMp2UpILp4/

В случае одноуровневых областей (областей, которые не находятся в прямой иерархии родитель-потомок), $ emit и $ broadcast не будут связываться с одноуровневыми областями.

enter image description here

Для получения более подробной информации, пожалуйста, обратитесь к http://yogeshtutorials.blogspot.in/2015/12/event-based-communication-between-angularjs-controllers.html

18
Yogesh

@ Эдди дал прекрасный ответ на заданный вопрос. Но я хотел бы обратить внимание на использование более эффективного подхода Pub/Sub.

Как этот ответ предполагает,

Подход $ broadcast/$ on не очень эффективен, так как он вещает на все области (в одном или обоих направлениях иерархии Scope). Хотя подход Pub/Sub гораздо более прямой. События получают только подписчики, так что не все системы будут работать.

вы можете использовать модуль angular-PubSub angular. добавив модуль 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); OR PubSub.unsubscribe('event-name');.

NOTE Не забудьте отписаться, чтобы избежать утечек памяти.

3
vinesh

Используйте RxJS в Сервисе

Как насчет ситуации, когда у вас есть Служба, которая удерживает состояние, например. Как я могу отправить изменения в эту Службу и другие случайные компоненты на странице, чтобы быть в курсе таких изменений? В последнее время боролся с этой проблемой

Создайте сервис с помощью RxJS Extensions для 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.

ДЕМО на PLNKR .

2
georgeawg