Я пытаюсь установить связь между двумя контроллерами. Я знаю, что это можно сделать, подняв событие, а затем используя $ rootScope. $ Broadcast, но не рекомендуется для крупномасштабных приложений. Я видел много сообщений в блогах, которые рекомендуют использовать службу для общения, но не могут преуспеть в реализации. Мой фактический код более сложный, но вот суть:
HTML:
<body ng-app="app">
<div ng-controller="MainCtrl">
<span>Source: {{count}}</span>
<button ng-click="updateCount()">Increase Count</button>
</div>
<div ng-controller="ListCtrl">
Destination: {{updatedCount}}
</div>
</body>
JS:
(function () {
var app = angular.module("app", []);
app.factory("ShareDataSvc", function ($log) {
var currentCount = 0;
var set = function (val) {
$log.info('Setting service value to: ' + currentCount);
currentCount = val;
}
var get = function () {
return currentCount;
}
return {
set: set,
get: get
}
});
app.controller("MainCtrl", ['$scope', 'ShareDataSvc', function ($scope, ShareDataSvc) {
$scope.count = ShareDataSvc.get();
$scope.updateCount = function () {
$scope.count = $scope.count + 1;
ShareDataSvc.set($scope.count);
}
}]);
app.controller("ListCtrl", ["$scope", "ShareDataSvc", function ($scope, ShareDataSvc) {
$scope.updatedCount = ShareDataSvc.get();
// trigger alert if count updated
$scope.triggerAlert = function () {
alert('Count updated!');
}
}]);
}());
Я пытаюсь понять, почему счетчик в пункте назначения не обновляется Angular, хотя он связан с данными. Я понимаю, что когда счетчик обновляется в SharedDataSvc, свойство updatedCount будет пересчитано. Что я здесь делаю неправильно? Конечным результатом является запуск предупреждения при каждом обновлении счетчика.
Вы столкнулись с проблемой старой копии по значению. Когда вы это сделаете
$scope.updatedCount = ShareDataSvc.get();
Обновленное свойство count устанавливается на значение, которое возвращается из вашей функции get, и поэтому не видит будущих изменений в отслеживаемом в вашей службе значении. У вас есть два варианта обойти это. Один из них - добавить часы к каждому из ваших контроллеров для отслеживания значения в службе. Не идеально. Во-вторых, чтобы свойство объекта в вашей службе отслеживало значение, а данные связывают этот объект с вашей областью. Что-то вроде (заметьте, я показываю только интересные части):
app.factory("ShareDataSvc", function ($log) {
var set = function (val) {
$log.info('Setting service value to: ' + currentCount);
this.data.count = val;
}
return {
data: {count: 0}
set: set
}
});
app.controller("MainCtrl", ['$scope', 'ShareDataSvc', function ($scope, ShareDataSvc) {
$scope.data = ShareDataSvc.data;
$scope.updateCount = function () {
ShareDataSve.data.count++; // and increment function in the service would be better
}
}]);
app.controller("ListCtrl", ["$scope", "ShareDataSvc", function ($scope, ShareDataSvc) {
$scope.data = ShareDataSvc.data;
}]);
Затем в вашем HTML
<body ng-app="app">
<div ng-controller="MainCtrl">
<span>Source: {{data.count}}</span>
<button ng-click="updateCount()">Increase Count</button>
</div>
<div ng-controller="ListCtrl">
Destination: {{data.count}}
</div>
</body>