You could write a service for this as mentioned in the comments or use events $scope.$emit
or $scope.$broadcast
.
Difference between these two. Emitting goes from childs up to $rootScope
and broadcasting goes down e.g. from $rootScope
to all children.
At start button click I emit an event with the interval promise and the other controller can bind a method on $rootScope
so it detects starting the interval.
Stopping can then be done with the promise passed with the event. But we need to $broadcast
a stop event after stopping the interval so the StartController
can clear the promise variable otherwise another start after stop wouldn't be possible.
Please have a look at the demo below or in this fiddle.
Update 10.10.2015
As you mentioned in the comments your use-case is different than what I coded and stopping an interval with changing to a different controller is easier than the event stuff.
Add your counter to ´$rootScope´ to have it displayed even after route change. I think otherwise the value would be destroyed with your controller.
Then pass your promise to your new state as stateParams
so you can stop the interval. That should also work for ngRoute
but then it should be done with $routeParams
.
I'm hiding the stop button if the interval is not started to avoid the code to check if there is a promise.
You can find the demo with ui.router
in this fiddle.
angular.module('demoApp', [])
.controller('TimerController', TimerController)
.controller('StopController', StopController);
function TimerController($scope, $interval) {
var self = this,
intPromise;
$scope.$on('timerEvent:stopped', function() {
intPromise = null; // timer stopped in other controller
});
this.start = function() {
if (!intPromise) {
intPromise = $interval(update, 1000);
$scope.$emit('timerEvent:start', intPromise);
}
}
function update() {
self.value = Math.round(Math.random()*100, 0);
}
}
function StopController($rootScope, $interval) {
var self = this;
$rootScope.$on('timerEvent:start', function(evt, promise) {
console.log(promise);
self.timerPromise = promise;
});
this.stop = function() {
console.log('stoppin', self.timerPromise);
if ( self.timerPromise ) {
$interval.cancel(self.timerPromise);
$rootScope.$broadcast('timerEvent:stopped');
}
};
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demoApp">
<div ng-controller="TimerController as timerCtrl">
<button ng-click="timerCtrl.start()">start</button>
{{timerCtrl.value}}
</div>
<div ng-controller="StopController as stopCtrl">
<button ng-click="stopCtrl.stop()">stop</button>
</div>