Передача переменных между контроллерами в AngularJS
Быстрый ответ
В AngularJS для обмена информацией между контроллерами наиболее эффективно использовать сервисы. Приведём пример такого сервиса, который легко включить в ваш проект:
// Создаём сервис для общих переменных
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
позволяет упростить операции чтения, записи и изменения общих переменных в любом из контроллеров.
Связываемся с переменными, чтобы избежать проблем
Не забывайте о важности точки в привязках! Игнорирование точки может приводить к потере функциональности, так как создание свойств в дочерних областях видимости может оказаться не очевидным и вызвать ошибки из-за специфики прототипного наследования.
// В сервисе
this.sharedObject = { someValue: '' };
// В контроллере
$scope.model = SharedVars.sharedObject;
// В шаблоне
<input ng-model="model.someValue">
Отведение предпочтения $rootScope
для глобального доступа к данным может казаться привлекательным, но часто при этом возникают проблемы с привязками и трудностями в отладке. В подобных случаях лучше уделить внимание сервисам или фабрикам с целью обеспечения возможности повторного использования данных и модульности.
По кругу цеха: мы строим фабрики!
Фабрики тоже весьма полезны для обмена информацией между контроллерами. Их преимущество заключается в том, что данные создаются только при первом необходимом обращении к ним, что позволяет избежать ненужного расхода памяти.
// Объявляем фабрику
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
могут служить инструментом уведомления о изменении данных в разных частях приложения.
app.controller('CtrlE', function($scope) {
$scope.doSomething = function() {
$scope.$emit('dataUpdated', someData);
};
});
app.controller('CtrlF', function($scope) {
$scope.$on('dataUpdated', function(event, receivedData) {
// Обрабатываем полученные данные
});
});
Однако стоит помнить, что событийный подход, реализующийся при работе с Angular, следует использовать с осторожностью, т.к. он может значительно усложнить архитектуру приложения.
Визуализация
Для большей наглядности можно представить обмен данными между контроллерами как взаимодействие двух астронавтов, которые используют один и тот же космический корабль для передачи данных:
Астронавт А (👨🚀): Хранит "DataX" (🔧)
Астронавт B (👩🚀): Желает получить "DataX" (🔧)
Передача данных через "сервис-корабль" происходит так:
👨🚀 ➡️ 🚀.setDataX(🔧) // Астронавт А передает данные
Астронавт B забирает данные:
👩🚀 ⬅️ 🚀.getDataX() // Астронавт B получает данные
Такое взаимодействие позволяет обоим астронавтам делиться данными, не сталкиваясь друг с другом напрямую, поскольку они используют сервис-корабль.
Рекомендации по стилю кодирования для вашего душевного спокойствия
Вот несколько дельных советов, основанных на проверенных временем практиках кодирования:
- Привязывайте данные к свойствам объектов для избежания конфликтов с родительским контекстом.
- Используйте
$root
с осторожностью; это может указывать на нежелательное появление глобальных данных. - Инвестируйте время в комментирование и составление документации к вашему коду, чтобы улучшить его понимание и процесс поддержки.
- Применяйте хэш-таблицы в сервисах для более эффективного управления состояниями и ссылками в сложных случаях.
Полезные материалы
- Документация AngularJS – Официальное руководство по обмену информацией между контроллерами.
- Обсуждение на Stack Overflow: Обмен данными – Разнообразные подходы сообщества к коммуникации между контроллерами.
- Документация AngularJS $rootScope.Scope – Глубокая проработка
$rootScope
. - Документация AngularJS Services – Использование сервисов в AngularJS для сохранения и обмена информацией.
- Документация AngularJS $rootScope.Scope#$on – Событийная связь между контроллерами.
- Обмен состояниями в UI-Router – Управление состояниями с помощью resolve в UI-Router.
- Thinkster: Использование сервисов для обмена информацией – Руководство по созданию сервисов в AngularJS.