angular.module('telavox.test', []) .factory('MySimulatedSlowHTTPService', function($q, $timeout, $rootScope) { var myservice = {}; myservice._initialized = false; myservice.refresh = function() { var deferred = $q.defer(); $timeout(function() { // Simulated slow fetch from an HTTP server var randomnumber=Math.floor(Math.random()*11); var randomLengthList = ['Item 1']; for (var i=0; i < randomnumber; i++) { randomLengthList = randomLengthList.concat(randomLengthList); } deferred.resolve(randomLengthList); if (myservice._initialized) { $rootScope.$broadcast('newList', deferred.promise); } myservice._initialized = true; }, 3000); myservice.listPromise = deferred.promise; return deferred.promise; }; myservice.refresh(); return myservice; }) .controller('MyListLengthAddedController', function($scope, $timeout, MySimulatedSlowHTTPService) { $scope.watchCallbackCalls = 0; function updateList(newList) { $scope.watchCallbackCalls++; $scope.myListLengthAdded = newList.length + 1; } MySimulatedSlowHTTPService.listPromise.then(function(newList) { updateList(newList); }, function(error) { $scope.myListLengthAdded = 1; $scope.error = error; }); $scope.$on('newList', function(ev, newListPromise) { newListPromise.then(function(newList) { updateList(newList); }, function(error) { // Ignored. Different error path than the initial since // we might have succeeded with our (fake) HTTP request // previously. }); }); $timeout(function() { MySimulatedSlowHTTPService.refresh(); }, 10000); }) .controller('MyListLengthController', function($scope, MySimulatedSlowHTTPService) { MySimulatedSlowHTTPService.listPromise.then(function(mylist) { // Deliberate choice to not update respond to further updates. $scope.myListLength = mylist.length; }); });
<div ng-app="telavox.test"> <div> <div class="controller" data-ng-controller="MyListLengthAddedController"> If I added one element, the list length would be {{myListLengthAdded}}.<br/> My watch callback was called {{watchCallbackCalls}} times. </div> <div class="controller" data-ng-controller="MyListLengthController"> My current list length is {{myListLength}}. </div> </div> </div>
</style> <!-- Ugly Hack due to jsFiddle issue: http://goo.gl/BUfGZ --> <link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css"> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script> <style> .error { color: red; } .controller { border: thin solid green; padding: 0.3em; margin: 0.3em; }