Я пытаюсь обмениваться данными между контроллерами. Вариант использования - это многошаговая форма, данные, введенные в один вход, впоследствии используются в нескольких местах отображения за пределами исходного контроллера. Код ниже и в jsfiddle здесь .
HTML
<div ng-controller="FirstCtrl">
<input type="text" ng-model="FirstName"><!-- Input entered here -->
<br>Input is : <strong>{{FirstName}}</strong><!-- Successfully updates here -->
</div>
<hr>
<div ng-controller="SecondCtrl">
Input should also be here: {{FirstName}}<!-- How do I automatically updated it here? -->
</div>
JS
// declare the app with no dependencies
var myApp = angular.module('myApp', []);
// make a factory to share data between controllers
myApp.factory('Data', function(){
// I know this doesn't work, but what will?
var FirstName = '';
return FirstName;
});
// Step 1 Controller
myApp.controller('FirstCtrl', function( $scope, Data ){
});
// Step 2 Controller
myApp.controller('SecondCtrl', function( $scope, Data ){
$scope.FirstName = Data.FirstName;
});
Любая помощь очень ценится.
javascript
angularjs
johnkeese
источник
источник
Ответы:
Простое решение состоит в том, чтобы ваша фабрика возвращала объект и позволяла вашим контроллерам работать со ссылкой на тот же объект:
JS:
HTML:
Демо: http://jsfiddle.net/HEdJF/
Когда приложения становятся больше, сложнее и сложнее для тестирования, вы, возможно, не захотите выставлять весь объект таким способом, а вместо этого предоставите ограниченный доступ, например, через геттеры и сеттеры:
При таком подходе контроллеры-потребители должны обновить фабрику новыми значениями и отслеживать изменения, чтобы получить их:
HTML:
Демо: http://jsfiddle.net/27mk1n1o/
источник
return { FirstName: '' };
или возвращающий объект, содержащий методы, которые взаимодействуют с объектом, было бы не предпочтительно возвращать экземпляр класса (function
), чтобы при использовании вашего объекта он имел определенный тип и не только объект{}" ?newValue !== oldValue
наперед, функция слушателя не нуждается в проверке, потому что Angular не выполняет функцию, если oldValue и newValue совпадают. Единственное исключение - если вы заботитесь о начальном значении. См .: docs.angularjs.org/api/ng/type/$rootScope.Scope#$watchЯ предпочитаю не использовать
$watch
для этого. Вместо того, чтобы назначать весь сервис области видимости контроллера, вы можете назначить только данные.JS:
HTML:
В качестве альтернативы вы можете обновить данные сервиса прямым методом.
JS:
источник
Существует много способов обмена данными между контроллерами.
Объяснение каждого метода:
Я не собираюсь объяснять, поскольку это уже кем-то объяснено
с помощью
$state.go
$stateparam
работает аналогично$state.go
, вы передаете его как объект от контроллера отправителя и собираете в контроллере получателя с помощью stateparamс помощью
$rootscope
(а) отправка данных от дочернего к родительскому контроллеру
(б) отправка данных от родителя к дочернему контроллеру
источник
Я создал фабрику, которая контролирует общую область между шаблоном пути маршрута, поэтому вы можете поддерживать общие данные только тогда, когда пользователи переходят по одному и тому же родительскому пути маршрута.
Таким образом, если пользователь перейдет к другому пути маршрута, например, «/ Поддержка», общие данные для пути «/ Клиент» будут автоматически уничтожены. Но если вместо этого пользователь перейдет к «дочерним» путям, таким как «/ Customer / 1» или «/ Customer / list», область действия не будет уничтожена.
Вы можете увидеть образец здесь: http://plnkr.co/edit/OL8of9
источник
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){ ... })
если у вас есть ui.routerЕсть несколько способов обмена данными между контроллерами
Как мы знаем
$rootscope
это не предпочтительный способ передачи данных или обмена данными, потому что это глобальная область, которая доступна для всего приложенияДля обмена данными между контроллерами Angular Js лучшими практиками являются, например, сервисы Angular.
.factory
,.service
Для справки
В случае передачи данных от родителей к контроллеру ребенка вы можете получить прямой доступ родительских данных в контроллере через ребенок
$scope
Если вы используете ,
ui-router
то вы можете использовать ,$stateParmas
чтобы передать параметры URL , какid
,name
,key
, и т.д.$broadcast
также хороший способ передачи данных между контроллерами от родителя к потомку и$emit
передачи данных от потомка к родительским контроллерамHTML
JS
Обратитесь по данной ссылке, чтобы узнать больше о
$broadcast
источник
Самое простое решение:
Я использовал сервис AngularJS .
Шаг 1: Я создал службу AngularJS с именем SharedDataService.
Шаг 2: Создайте два контроллера и используйте созданный выше сервис.
Шаг 3: Просто используйте созданные контроллеры в представлении.
Чтобы увидеть рабочее решение этой проблемы, пожалуйста, нажмите на ссылку ниже
https://codepen.io/wins/pen/bmoYLr
.html файл:
источник
FirstCtrl
является родителем и получает обещание, котороеSecondCtrl
(ребенок) также понадобится? Я не хочу делать два вызова API. Спасибо.Есть другой способ без использования $ watch, используя angular.copy:
источник
Есть несколько способов сделать это.
События - уже объяснили хорошо.
UI роутер - объяснено выше.
*
*
источник
Не уверен, где я выбрал этот шаблон, но для совместного использования данных между контроллерами и сокращения $ rootScope и $ scope это прекрасно работает. Это напоминает репликацию данных, когда у вас есть издатели и подписчики. Надеюсь, поможет.
Сервис:
Контроллер, который получает новые данные, то есть Издатель, сделал бы что-то вроде этого ...
Контроллер, который также использует эти новые данные, который называется Подписчик, сделал бы что-то вроде этого ...
Это будет работать для любого сценария. Поэтому, когда первичный контроллер инициализируется и получает данные, он вызывает метод changeData, который затем передает это всем подписчикам этих данных. Это уменьшает связь наших контроллеров друг с другом.
источник
sharedDataEventHub.changeData(newData)
sharedDataEventHub.changeData(newData)
любой дочерний элемент или контроллер, который зависит от этих данных, где-то в их теле контроллера:sharedDataEventHub.onChangeData($scope, function(obj) { vm.myObject = obj.data; });
Если вы использовали пользовательский интерфейс -Router это может быть введено из конфига состояния.Просто сделайте это просто (протестировано с v1.3.15):
источник
dummy
является глобальным для обоих контроллеров, а не совместно используемым более модульным способом через наследование с $ scope или controllerAs или с помощью службы.