Created
November 1, 2013 03:03
-
-
Save alexanderlperez/7260457 to your computer and use it in GitHub Desktop.
NOTE: this code is a little stale and *highly* coupled Using the setTimeout family of functions in an Angular.js module: since the JS engine on the browser updates variables outside of the angular event-loop, $apply() is required to update any values changed outside of a controller. You can see the need for $apply() in Timer.prototype.incrementT…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
/* | |
Timer Ver. 3 | |
The purpose of this series of fiddles is to explore properly dividing the program logic into model and controller | |
while appropriately executing the Angular.js 'way' of achieving that result | |
- the model has been moved outside the controller | |
*/ | |
function timerCtrl($scope) { | |
$scope.Timer = new Timer($scope); | |
} | |
function Timer(scope) { | |
this.scope = scope; | |
this.timeElapsed = 0; | |
this.getTimeElapsed = "00:00"; | |
this.intervalTimer = null; | |
this.timerStarted = false; | |
} | |
Timer.prototype = { | |
start: function () { | |
//prevent orphaning intervalTimer - by overwriting it with a | |
//reference to another timer - every time the start button is | |
//clicked | |
if (!this.timerStarted) { | |
//bind must be used here since, internally, setInterval's this is bound to the global scope | |
//now we can refer to $scope as 'this' in Timer | |
this.intervalTimer = setInterval(this.incrementTimer.bind(this.scope), 1000); | |
this.timerStarted = true; | |
} | |
}, | |
pause: function () { | |
this.timerStarted = false; | |
clearInterval(this.intervalTimer); | |
}, | |
reset: function () { | |
this.timerStarted = false; | |
this.timeElapsed = 0; | |
this.getTimeElapsed = "00:00"; | |
clearInterval(this.intervalTimer); | |
}, | |
incrementTimer: function () { | |
//convenience function: convert seconds to minutes | |
function formatElapsedTime(time) { | |
var minutes = Math.floor(time / 60), | |
seconds = Math.floor(time % 60); | |
if (seconds < 10) seconds = "0" + seconds.toString(); | |
else seconds.toString(); | |
if (minutes < 10) minutes = "0" + minutes.toString(); | |
else minutes.toString(); | |
return minutes + ":" + seconds; | |
} | |
this.Timer.timeElapsed++; | |
this.Timer.getTimeElapsed = formatElapsedTime(this.Timer.timeElapsed); | |
//update Angular's binding process | |
//Question: why do I need $apply here but not in Timer.reset()? | |
//Answer: all event callbacks outside of the Angular execution context (effectively its event loop), | |
// in this case setInterval's event within the normal browser event loop, need $apply() to | |
// activate the $watch list loop so that Angular knows to check all the expressions in the view | |
// for any changes, in this case the {{Timer.getTimeElapsed}} expression in the HTMLT | |
this.$apply(); | |
} | |
}; | |
</script> | |
<div ng-app ng-controller="timerCtrl"> | |
<h1>{{Timer.getTimeElapsed}}</h1> | |
<button type="button" ng-click="Timer.start()">Start</button> | |
<button type="button" ng-click="Timer.pause()">Pause</button> | |
<button type="button" ng-click="Timer.reset()">Reset</button> | |
</div> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment