aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPete Bacon Darwin2013-12-17 22:53:28 +0000
committerPete Bacon Darwin2013-12-17 22:53:28 +0000
commit73c66715c9a13b0fdacf98a9e9f237063a97ebc3 (patch)
tree4067f429946d0a99c82ae1ad1f7917ae5c62e4b9
parentcb29632a5802e930262919b3db64ca4806c5cfc7 (diff)
downloadangular.js-73c66715c9a13b0fdacf98a9e9f237063a97ebc3.tar.bz2
docs(bootstrap-prettify): fix $timeout issues and update related docs
End 2 end tests wait for all `$timeout`s to be run before completing the test. This was problematic where we were using timeouts that restarted themselves because there would never be a point when all timeouts had completed, causing the tests to hang. To fix this $timeout had been monkey-patched but this caused other issue itself. Now that we have $interval we don't need to use $timeout handlers that re-trigger the $timeout so we can ditch the monkey-patch. This commit tidies up any examples that are using this approach and changes them to use $interval instead. Closes #5232
-rw-r--r--docs/components/angular-bootstrap/bootstrap-prettify.js12
-rw-r--r--docs/content/guide/dev_guide.services.managing_dependencies.ngdoc7
-rw-r--r--docs/content/guide/directive.ngdoc26
-rw-r--r--docs/content/guide/scope.ngdoc4
-rw-r--r--src/ng/interval.js82
-rw-r--r--src/ng/timeout.js87
6 files changed, 99 insertions, 119 deletions
diff --git a/docs/components/angular-bootstrap/bootstrap-prettify.js b/docs/components/angular-bootstrap/bootstrap-prettify.js
index 72c136d1..5129c4e1 100644
--- a/docs/components/angular-bootstrap/bootstrap-prettify.js
+++ b/docs/components/angular-bootstrap/bootstrap-prettify.js
@@ -215,17 +215,7 @@ directive.ngEmbedApp = ['$templateCache', '$browser', '$rootScope', '$location',
}];
this.html5Mode = angular.noop;
});
- $provide.decorator('$timeout', ['$rootScope', '$delegate', function($rootScope, $delegate) {
- return angular.extend(function(fn, delay) {
- if (delay && delay > 50) {
- return setTimeout(function() {
- $rootScope.$apply(fn);
- }, delay);
- } else {
- return $delegate.apply(this, arguments);
- }
- }, $delegate);
- }]);
+
$provide.decorator('$rootScope', ['$delegate', function($delegate) {
embedRootScope = $delegate;
diff --git a/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc b/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc
index b069f4bb..a0d95d4a 100644
--- a/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc
+++ b/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc
@@ -50,7 +50,7 @@ of which depend on other services that are provided by the Angular framework:
* @param {*} message Message to be logged.
*/
function batchLogModule($provide){
- $provide.factory('batchLog', ['$timeout', '$log', function($timeout, $log) {
+ $provide.factory('batchLog', ['$interval', '$log', function($interval, $log) {
var messageQueue = [];
function log() {
@@ -58,11 +58,10 @@ of which depend on other services that are provided by the Angular framework:
$log('batchLog messages: ', messageQueue);
messageQueue = [];
}
- $timeout(log, 50000);
}
// start periodic checking
- log();
+ $interval(log, 50000);
return function(message) {
messageQueue.push(message);
@@ -88,7 +87,7 @@ of which depend on other services that are provided by the Angular framework:
Things to notice in this example:
-* The `batchLog` service depends on the built-in {@link api/ng.$timeout $timeout} and
+* The `batchLog` service depends on the built-in {@link api/ng.$interval $interval} and
{@link api/ng.$log $log} services, and allows messages to be logged into the
`console.log` in batches.
* The `routeTemplateMonitor` service depends on the built-in {@link api/ngRoute.$route
diff --git a/docs/content/guide/directive.ngdoc b/docs/content/guide/directive.ngdoc
index b6b74a97..b3925bfc 100644
--- a/docs/content/guide/directive.ngdoc
+++ b/docs/content/guide/directive.ngdoc
@@ -528,8 +528,10 @@ where:
* `attrs` is an object with the normalized attribute names and their corresponding values.
In our `link` function, we want to update the displayed time once a second, or whenever a user
-changes the time formatting string that our directive binds to. We also want to remove the timeout
-if the directive is deleted so we don't introduce a memory leak.
+changes the time formatting string that our directive binds to. We will use the `$interval` service
+to call a handler on a regular basis. This is easier than using `$timeout` but also works better with
+end 2 end testing, where we want to ensure that all $timeouts have completed before completing the test.
+We also want to remove the `$interval` if the directive is deleted so we don't introduce a memory leak.
<example module="docsTimeDirective">
<file name="script.js">
@@ -537,7 +539,7 @@ if the directive is deleted so we don't introduce a memory leak.
.controller('Ctrl2', function($scope) {
$scope.format = 'M/d/yy h:mm:ss a';
})
- .directive('myCurrentTime', function($timeout, dateFilter) {
+ .directive('myCurrentTime', function($interval, dateFilter) {
function link(scope, element, attrs) {
var format,
@@ -552,20 +554,14 @@ if the directive is deleted so we don't introduce a memory leak.
updateTime();
});
- function scheduleUpdate() {
- // save the timeoutId for canceling
- timeoutId = $timeout(function() {
- updateTime(); // update DOM
- scheduleUpdate(); // schedule the next update
- }, 1000);
- }
-
element.on('$destroy', function() {
- $timeout.cancel(timeoutId);
+ $interval.cancel(timeoutId);
});
- // start the UI update process.
- scheduleUpdate();
+ // start the UI update process; save the timeoutId for canceling
+ timeoutId = $interval(function() {
+ updateTime(); // update DOM
+ }, 1000);
}
return {
@@ -583,7 +579,7 @@ if the directive is deleted so we don't introduce a memory leak.
There are a couple of things to note here.
Just like the `module.controller` API, the function argument in `module.directive` is dependency
-injected. Because of this, we can use `$timeout` and `dateFilter` inside our directive's `link`
+injected. Because of this, we can use `$interval` and `dateFilter` inside our directive's `link`
function.
We register an event `element.on('$destroy', ...)`. What fires this `$destroy` event?
diff --git a/docs/content/guide/scope.ngdoc b/docs/content/guide/scope.ngdoc
index 70224c82..da35a1b8 100644
--- a/docs/content/guide/scope.ngdoc
+++ b/docs/content/guide/scope.ngdoc
@@ -259,8 +259,8 @@ the `$digest` phase. This delay is desirable, since it coalesces multiple model
For mutations to be properly observed, you should make them only within the {@link
api/ng.$rootScope.Scope#methods_$apply scope.$apply()}. (Angular APIs do this
implicitly, so no extra `$apply` call is needed when doing synchronous work in controllers,
- or asynchronous work with {@link api/ng.$http $http} or {@link
- api/ng.$timeout $timeout} services.
+ or asynchronous work with {@link api/ng.$http $http}, {@link api/ng.$timeout $timeout}
+ or {@link api/ng.$interval $interval} services.
4. **Mutation observation**
diff --git a/src/ng/interval.js b/src/ng/interval.js
index 2ad3a7f1..1ae13648 100644
--- a/src/ng/interval.js
+++ b/src/ng/interval.js
@@ -32,6 +32,88 @@ function $IntervalProvider() {
* @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
* will invoke `fn` within the {@link ng.$rootScope.Scope#methods_$apply $apply} block.
* @returns {promise} A promise which will be notified on each iteration.
+ *
+ * @example
+ <doc:example module="time">
+ <doc:source>
+ <script>
+ function Ctrl2($scope,$interval) {
+ $scope.format = 'M/d/yy h:mm:ss a';
+ $scope.blood_1 = 100;
+ $scope.blood_2 = 120;
+
+ var stop;
+ $scope.fight = function() {
+ // Don't start a new fight if we are already fighting
+ if ( angular.isDefined(stop) ) return;
+
+ stop = $interval(function() {
+ if ($scope.blood_1 > 0 && $scope.blood_2 > 0) {
+ $scope.blood_1 = $scope.blood_1 - 3;
+ $scope.blood_2 = $scope.blood_2 - 4;
+ } else {
+ $interval.cancel(stop);
+ }
+ }, 100);
+ };
+
+ $scope.stopFight = function() {
+ $interval.cancel(stop);
+ stop = undefined;
+ };
+
+ $scope.resetFight = function() {
+ $scope.blood_1 = 100;
+ $scope.blood_2 = 120;
+ }
+ }
+
+ angular.module('time', [])
+ // Register the 'myCurrentTime' directive factory method.
+ // We inject $interval and dateFilter service since the factory method is DI.
+ .directive('myCurrentTime', 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 ofter the DOM element was removed.
+ element.bind('$destroy', function() {
+ $interval.cancel(stopTime);
+ });
+ }
+ });
+ </script>
+
+ <div>
+ <div ng-controller="Ctrl2">
+ Date format: <input ng-model="format"> <hr/>
+ Current time is: <span my-current-time="format"></span>
+ <hr/>
+ Blood 1 : <font color='red'>{{blood_1}}</font>
+ Blood 2 : <font color='red'>{{blood_2}}</font>
+ <button type="button" data-ng-click="fight()">Fight</button>
+ <button type="button" data-ng-click="stopFight()">StopFight</button>
+ <button type="button" data-ng-click="resetFight()">resetFight</button>
+ </div>
+ </div>
+
+ </doc:source>
+ </doc:example>
*/
function interval(fn, delay, count, invokeApply) {
var setInterval = $window.setInterval,
diff --git a/src/ng/timeout.js b/src/ng/timeout.js
index 51e627b9..511a0a05 100644
--- a/src/ng/timeout.js
+++ b/src/ng/timeout.js
@@ -32,93 +32,6 @@ function $TimeoutProvider() {
* @returns {Promise} Promise that will be resolved when the timeout is reached. The value this
* promise will be resolved with is the return value of the `fn` function.
*
- * @example
- <doc:example module="time">
- <doc:source>
- <script>
- function Ctrl2($scope,$timeout) {
- $scope.format = 'M/d/yy h:mm:ss a';
- $scope.blood_1 = 100;
- $scope.blood_2 = 120;
-
- var stop;
- $scope.fight = function() {
- stop = $timeout(function() {
- if ($scope.blood_1 > 0 && $scope.blood_2 > 0) {
- $scope.blood_1 = $scope.blood_1 - 3;
- $scope.blood_2 = $scope.blood_2 - 4;
- $scope.fight();
- } else {
- $timeout.cancel(stop);
- }
- }, 100);
- };
-
- $scope.stopFight = function() {
- $timeout.cancel(stop);
- };
-
- $scope.resetFight = function() {
- $scope.blood_1 = 100;
- $scope.blood_2 = 120;
- }
- }
-
- angular.module('time', [])
- // Register the 'myCurrentTime' directive factory method.
- // We inject $timeout and dateFilter service since the factory method is DI.
- .directive('myCurrentTime', function($timeout, dateFilter) {
- // return the directive link function. (compile function not needed)
- return function(scope, element, attrs) {
- var format, // date format
- timeoutId; // timeoutId, 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();
- });
-
- // schedule update in one second
- function updateLater() {
- // save the timeoutId for canceling
- timeoutId = $timeout(function() {
- updateTime(); // update DOM
- updateLater(); // schedule another update
- }, 1000);
- }
-
- // listen on DOM destroy (removal) event, and cancel the next UI update
- // to prevent updating time ofter the DOM element was removed.
- element.bind('$destroy', function() {
- $timeout.cancel(timeoutId);
- });
-
- updateLater(); // kick off the UI update process.
- }
- });
- </script>
-
- <div>
- <div ng-controller="Ctrl2">
- Date format: <input ng-model="format"> <hr/>
- Current time is: <span my-current-time="format"></span>
- <hr/>
- Blood 1 : <font color='red'>{{blood_1}}</font>
- Blood 2 : <font color='red'>{{blood_2}}</font>
- <button type="button" data-ng-click="fight()">Fight</button>
- <button type="button" data-ng-click="stopFight()">StopFight</button>
- <button type="button" data-ng-click="resetFight()">resetFight</button>
- </div>
- </div>
-
- </doc:source>
- </doc:example>
*/
function timeout(fn, delay, invokeApply) {
var deferred = $q.defer(),