Передача объекта между контроллерами через $emit и $on в AngularJS

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

В AngularJS для обеспечения коммуникации между контроллерами используются $scope.$emit и $scope.$on. Для инициации события используйте $scope.$emit, а для обработки этого события — $scope.$on. У вас получится, что события будут отправляться вверх по иерархии областей видимости при помощи $scope.$emit, а затем их можно будет получать через $scope.$on. Взгляните на пример:

JS
Скопировать код
// В контексте дочернего контроллера
$scope.$emit('event', { data: 'Вверх!' });

// В контексте родительского контроллера
$scope.$on('event', function(event, args) {
  console.log(args.data); // Выведет 'Вверх!'
});

Важно: Обязательно отмените подписку на события с помощью функции, которую возвращает $scope.$on, когда область видимости уничтожается:

JS
Скопировать код
var offEvent = $scope.$on('event', function(event, args) { /* ... */ });

$scope.$on('$destroy', offEvent);
Кинга Идем в IT: пошаговый план для смены профессии

$rootScope: Когда контроллеры не связаны

Если контроллеры между собой не связаны (т.е., они не находятся в иерархии родитель-потомок), можно использовать $rootScope. Методы $rootScope.$broadcast или $rootScope.$emit позволяют инициировать события.

JS
Скопировать код
// Контроллеры, нет связи между ними
$rootScope.$broadcast('globalEvent', { data: 'Оповещаем глобально!' });

// Другой контроллер, прослушивающий глобальные события
$rootScope.$on('globalEvent', function(event, args) {
  console.log(args.data); // Выведет 'Оповещаем глобально!'
});

Эффективное использование сервиса

Чтобы избежать медленной передачи данных между контроллерами, лучше всего использовать сервисы, которые отлично подходят для хранения общих данных.

JS
Скопировать код
app.service('SharedService', function() {
  var sharedData = {};

  return {
    setData: function(data) {
      sharedData = data;
    },
    getData: function() {
      return sharedData;
    }
  };
});
Подробнее об этом расскажет наш спикер на видео
skypro youtube speaker

Повышение производительности: умное использование событий

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

Визуализация

Давайте представим, что $scope.$emit и $scope.$on – подобны радиовышке и приемникам:

Markdown
Скопировать код
              📡 **Радиовышка** 📡
                    ($scope.$emit)
                          |
           🎵-----------------------------🎵
          |     |     |     |     |     |     | 
        📻    📻    📻    📻    📻    📻    📻  
      ($scope.$on) ($scope.$on) ... ($scope.$on)

Радиовышка 📡 транслирует сигналы:

JS
Скопировать код
$scope.$emit('concertName', data); // Концерт начался!

Приёмники 📻 настроены на приём этих сигналов через $scope.$on. Мы просто в восторге!

JS
Скопировать код
$scope.$on('concertName', function(event, data) {
  // Наслаждаемся концертом
});

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

JS
Скопировать код
// Родительский контроллер инициирует событие для дочерних контроллеров
$scope.$broadcast('downEvent', { data: 'Вниз по дереву!' });

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

JS
Скопировать код
var globalOff = $rootScope.$on('globalEvent', function() {}); 

$scope.$on('$destroy', function() {
  globalOff();   // Чтобы предотвратить утечку памяти
});

Организация событий: простота – залог успешности

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

Полезные материалы

  1. Официальная документация AngularJS — подробное описание методов $emit, $broadcast и $on.
  2. Вопросы по тегам 'angularjs+scope+events' на Stack Overflow — обсуждение и решение проблем, связанных с событиями в AngularJS.
  3. AngularJS tutorials и курсы на Thinkster — детальное изучение обработки событий и двустороннего связывания данных в AngularJS.
  4. Учебное видео: Создание погодного приложения на JavaScript — практическое применение JavaScript (особенность: без AngularJS).
  5. Envato Tuts+ – сериалы о создании стартапов с использованием PHP — персональные идеи для кода и потенциальный источник вдохновения для AngularJS.
Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Как инициировать событие в AngularJS?
1 / 5