Reputation: 7225
I have different pages on may application which have their own controllers. One of them has an $interval function, let's say a timer. Click on a button will start this interval function, which updates itself every second. What i want to have is, i want to be able to go to any other page in my application (calling different controllers), but i want my interval to continue running until i stop it explicitly from the first controller. A rootScope interval so to speak. How can i do it?
EDIT: Thanks to Chris and Patrick i now have a simple Service, looks like this:
.service('TimerService', function($interval) {
var promise;
var timerSeconds = 0;
this.start = function () {
promise = $interval(function () {
timerSeconds++;
}, 1000);
};
this.stop = function () {
promise.cancel(interval);
timerSeconds = 0;
};
this.getTimer = function() {
return timerSeconds;
}
})
I store also my current value (timerSeconds) in this service. But how can i sync this value to my controller? The service increments the timerSeconds, and at the beginning of my controller i read it from this service through its getTimer() function, but it clearly will not be updated on my controller. How can i sync this service attribute with my local attribute?
EDIT:
when i define my service attribute as an object and the timerSeconds as number inside that object (it seems primitives cannot be synced):
var timer = {seconds : 0};
this.getTimer = function() {
return timer;
}
and get this object from my controller through that getter:
vm.timer = TimerService.getTimer();
they are all in sync.
Upvotes: 1
Views: 1190
Reputation: 6958
Don't bother adding it to $rootScope. Use a service that can be used anywhere in the app. Here is a singleton timer that can start and stop. Define the intervalTimeout in the service itself, or if you want to be really flexible, do so in a provider (probably overkill for this example).
angular.module('myApp', [])
.service('AppCallback', function ($interval) {
var states = states = {
PENDING: 0,
STARTED: 1
}, intervalTimeout = 3000, // Set this
interval;
this.states = states;
this.state = states.PENDING;
this.start = function (callback) {
if (this.state !== states.PENDING) {
return;
}
interval = $interval(callback, intervalTimeout);
this.state = states.STARTED;
}
this.stop = function () {
if (this.state !== states.STARTED) {
return;
}
$interval.cancel(interval);
this.state = states.PENDING;
};
})
.controller('MainController', function ($scope, AppCallback) {
var vm = {},
count = 0;
vm.toggle = function toggle() {
if (AppCallback.state === AppCallback.states.PENDING) {
AppCallback.start(function () {
vm.data = 'Ticked ' + (++count) + ' times.';
});
} else {
AppCallback.stop();
}
};
$scope.vm = vm;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MainController">
{{vm.data}}
<br />
<button ng-click="vm.toggle()">Toggle</button>
</div>
Upvotes: 2
Reputation: 27394
If you want to share any data between controllers the correct way is to use a service.
I would then create a service that allows you to stop and start this timer / interval.
The initial controller would kick this off and it would continue to "tick" forever until it is stopped.
Upvotes: 2