Reputation: 8080
I'm trying to update a view through a controller that sources its data from a service. For some reason, the view doesn't update when the service's data changes. I've distilled an example from my application here. I've tried all sorts of bindings ($scope.time = TimerService.value
, wrapped in a function, using $watch
- no success).
Note, in my original app, this is an array of objects and an object's attribute changes.
-- script.js --
var mod = angular.module('mymodule', []);
mod.service('TimerService', function() {
this.value = 0;
var self = this;
setInterval(function() {
self.value += 1;
}, 2000)
});
mod.controller('TimerCtrl', ['TimerService', '$scope', function(TimerService, $scope) {
$scope.time = TimerService.value;
$scope.$watch(function() {
return TimerService.value;
}, function(newValue) {
$scope.time = newValue;
}, true);
$scope.otherValue = '12345';
}]);
angular.element(document).ready(function() {
alert('start');
angular.bootstrap(document, ['mymodule']);
});
-- index.html --
<!DOCTYPE html>
<html>
<head>
<script src="./angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div ng-controller="TimerCtrl">
<h1>- {{ time }}-</h1>
<h2>{{ otherValue }}</h2>
</div>
</body>
</html>
Upvotes: 1
Views: 5565
Reputation: 8080
After spending some time with trial and error, I finally found the answer to the problem. In my example above (and my real application), the data gets changed outside of the angular scope (controller button click, http request, etc) which means a digest cycle is not getting kicked off. If I change the code to use $timeout()
, it works. Unfortunately, this doesn't entirely solve my problem of the data being changed outside of angular (I guess I need to integrate the rest into angular as well).
Update
I managed to perform changes outside of angular by using rootscope
in my service:
$rootscope.$apply(function() {
// perform variable update here.
self.value += 1;
});
This successfully propagates to the view.
Upvotes: 1
Reputation: 32716
Try
var app = angular.module('myApp', []);
var value = 0;
var timer = setInterval('Repeater()', 1000);
var Repeater = function () {
value++;
var scope = angular.element(document.getElementById('myApp')).scope();
console.log(scope);
scope.$apply(function () {
scope.time = value;
});
};
app.controller('TimerCtrl', ['$scope', function( $scope) {
}]);
credit to https://stackoverflow.com/a/16520050/356380
Upvotes: 0
Reputation: 1150
Try this
$scope.time = TimerService.value;
if(!$scope.$$phase) {
$scope.$apply();
}
Upvotes: 0