Передача переменных между контроллерами в AngularJS

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

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

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

В AngularJS для обмена информацией между контроллерами наиболее эффективно использовать сервисы. Приведём пример такого сервиса, который легко включить в ваш проект:

JS
Скопировать код
// Создаём сервис для общих переменных
app.service('SharedVars', function() {
  var store = {};

  this.set = function(key, value) { 
    store[key] = value;
  };

  this.get = function(key) {
    return store[key];
  };
});


app.controller('CtrlA', function(SharedVars) {
  SharedVars.set('sharedKey', 'value');
});

app.controller('CtrlB', function($scope, SharedVars) {
  $scope.sharedValue = SharedVars.get('sharedKey');
});

Таким образом, подключение сервиса SharedVars позволяет упростить операции чтения, записи и изменения общих переменных в любом из контроллеров.

Кинга Идем в IT: пошаговый план для смены профессии

Связываемся с переменными, чтобы избежать проблем

Не забывайте о важности точки в привязках! Игнорирование точки может приводить к потере функциональности, так как создание свойств в дочерних областях видимости может оказаться не очевидным и вызвать ошибки из-за специфики прототипного наследования.

JS
Скопировать код
// В сервисе
this.sharedObject = { someValue: '' };

// В контроллере
$scope.model = SharedVars.sharedObject;

// В шаблоне
<input ng-model="model.someValue">

Отведение предпочтения $rootScope для глобального доступа к данным может казаться привлекательным, но часто при этом возникают проблемы с привязками и трудностями в отладке. В подобных случаях лучше уделить внимание сервисам или фабрикам с целью обеспечения возможности повторного использования данных и модульности.

По кругу цеха: мы строим фабрики!

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

JS
Скопировать код
// Объявляем фабрику
app.factory('SharedData', function() {
  var data = { key: null };
  return {
    get key() { return data.key; },
    set key(newVal) { data.key = newVal; }
  };
});

// Используем фабрику в контроллерах
app.controller('CtrlC', function($scope, SharedData) {
  SharedData.key = 'newValue'; 
});

app.controller('CtrlD', function($scope, SharedData) {
  $scope.value = SharedData.key;
});

Фабрики предоставляют более удобный контроль и отлично подходят для управления сложной структурой приложений.

Взаимодействие контроллеров через события

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

JS
Скопировать код
app.controller('CtrlE', function($scope) {
  $scope.doSomething = function() {
    $scope.$emit('dataUpdated', someData);
  };
});

app.controller('CtrlF', function($scope) {
  $scope.$on('dataUpdated', function(event, receivedData) {
    // Обрабатываем полученные данные
  });
});

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

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

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

Markdown
Скопировать код
Астронавт А (👨‍🚀): Хранит "DataX" (🔧)
Астронавт B (👩‍🚀): Желает получить "DataX" (🔧)

Передача данных через "сервис-корабль" происходит так:

Markdown
Скопировать код
👨‍🚀 ➡️ 🚀.setDataX(🔧)  // Астронавт А передает данные

Астронавт B забирает данные:

Markdown
Скопировать код
👩‍🚀 ⬅️ 🚀.getDataX()  // Астронавт B получает данные

Такое взаимодействие позволяет обоим астронавтам делиться данными, не сталкиваясь друг с другом напрямую, поскольку они используют сервис-корабль.

Рекомендации по стилю кодирования для вашего душевного спокойствия

Вот несколько дельных советов, основанных на проверенных временем практиках кодирования:

  1. Привязывайте данные к свойствам объектов для избежания конфликтов с родительским контекстом.
  2. Используйте $root с осторожностью; это может указывать на нежелательное появление глобальных данных.
  3. Инвестируйте время в комментирование и составление документации к вашему коду, чтобы улучшить его понимание и процесс поддержки.
  4. Применяйте хэш-таблицы в сервисах для более эффективного управления состояниями и ссылками в сложных случаях.

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

  1. Документация AngularJS – Официальное руководство по обмену информацией между контроллерами.
  2. Обсуждение на Stack Overflow: Обмен данными – Разнообразные подходы сообщества к коммуникации между контроллерами.
  3. Документация AngularJS $rootScope.Scope – Глубокая проработка $rootScope.
  4. Документация AngularJS Services – Использование сервисов в AngularJS для сохранения и обмена информацией.
  5. Документация AngularJS $rootScope.Scope#$on – Событийная связь между контроллерами.
  6. Обмен состояниями в UI-Router – Управление состояниями с помощью resolve в UI-Router.
  7. Thinkster: Использование сервисов для обмена информацией – Руководство по созданию сервисов в AngularJS.