Exploring the AngularJS documentation for $interval
, I came across an interesting example demonstrating how to utilize $interval
in a controller to create a user-friendly timer in a view. The official example code can be found on the angularJS documentation page linked here.
In an attempt to enhance modularity, I endeavored to shift the code from the example controller into a service. However, I encountered difficulties as the service wasn't being connected to the view properly. To provide a clear demonstration of this issue, I have replicated it on this plnkr link where you can experiment with the code.
The main question at hand is what specific modifications are required in the provided plnkr code so that the mytimer
service is accessible in the view as a property of the controller importing the service?
To summarize, 'index.html` consists of:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8>
<title>Example - example-example109-production</title>
<script src="myTimer.js" type="text/javascript"></script>
<script src="exampleController.js" type="text/javascript"></script>
<script src="app.js" type="text/javascript"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
</head>
<body ng-app="intervalExample">
<div>
<div ng-controller="ExampleController">
<label>Date format: <input ng-model="mytimer.format"></label> <hr/>
Current time is: <span my-current-time="mytimer.format"></span>
<hr/>
Blood 1 : <font color='red'>{{mytimer.blood_1}}</font>
Blood 2 : <font color='red'>{{mytimer.blood_2}}</font>
<button type="button" data-ng-click="mytimer.fight()">Fight</button>
<button type="button" data-ng-click="mytimer.stopFight()">StopFight</button>
<button type="button" data-ng-click="mytimer.resetFight()">resetFight</button>
</div>
</div>
</body>
</html>
The content of app.js
:
angular.module('intervalExample',['ExampleController'])
Code inside exampleController.js
:
angular
.module('intervalExample', ['mytimer'])
.controller('ExampleController', function($scope, mytimer) {
$scope.mytimer = mytimer;
});
And finally, within myTimer.js
:
angular
.module('mytimer', [])
.service('mytimer', ['$rootScope', function($rootScope, $interval) {
var $this = this;
this.testvariable = "some value. ";
this.format = 'M/d/yy h:mm:ss a';
this.blood_1 = 100;
this.blood_2 = 120;
var stop;
this.fight = function() {
// Don't start a new fight if we are already fighting
if ( angular.isDefined(stop) ) return;
stop = $interval(function() {
if (this.blood_1 > 0 && this.blood_2 > 0) {
this.blood_1 = this.blood_1 - 3;
this.blood_2 = this.blood_2 - 4;
} else {
this.stopFight();
}
}, 100);
};
this.stopFight = function() {
if (angular.isDefined(stop)) {
$interval.cancel(stop);
stop = undefined;
}
};
this.resetFight = function() {
this.blood_1 = 100;
this.blood_2 = 120;
};
this.$on('$destroy', function() {
// Make sure that the interval is destroyed too
this.stopFight();
});
}])
// Register the 'myCurrentTime' directive factory method.
// We inject $interval and dateFilter service since the factory method is DI.
.directive('myCurrentTime', ['$interval', 'dateFilter',
function($interval, dateFilter) {
// return the directive link function. (compile function not needed)
return function(scope, element, attrs) {
var format, // date format
stopTime; // so that we can cancel the time updates
// used to update the UI
function updateTime() {
element.text(dateFilter(new Date(), format));
}
// watch the expression, and update the UI on change.
scope.$watch(attrs.myCurrentTime, function(value) {
format = value;
updateTime();
});
stopTime = $interval(updateTime, 1000);
// listen on DOM destroy (removal) event, and cancel the next UI update
// to prevent updating time after the DOM element was removed.
element.on('$destroy', function() {
$interval.cancel(stopTime);
});
}
}]);;
You can investigate all of the code mentioned above in "working" form by accessing this plnkr link where you can troubleshoot and pinpoint the solution to the problem. What precise adjustments should be made to the aforementioned code to allow users to interact with the service through the view effectively?