diff --git a/src/service/xhr.cache.js b/src/service/xhr.cache.js index 284321d77ed1..c6066a5c478a 100644 --- a/src/service/xhr.cache.js +++ b/src/service/xhr.cache.js @@ -20,10 +20,11 @@ * @param {boolean=} [verifyCache=false] If `true` then a result is immediately returned from cache * (if present) while a request is sent to the server for a fresh response that will update the * cached entry. The `callback` function will be called when the response is received. + * @param {boolean=} [sync=false] in case of cache hit execute `callback` synchronously. */ angularServiceInject('$xhr.cache', function($xhr, $defer, $log){ var inflight = {}, self = this; - function cache(method, url, post, callback, verifyCache){ + function cache(method, url, post, callback, verifyCache, sync){ if (isFunction(post)) { callback = post; post = null; @@ -31,7 +32,13 @@ angularServiceInject('$xhr.cache', function($xhr, $defer, $log){ if (method == 'GET') { var data, dataCached; if (dataCached = cache.data[url]) { - $defer(function() { callback(200, copy(dataCached.value)); }); + + if (sync) { + callback(200, copy(dataCached.value)); + } else { + $defer(function() { callback(200, copy(dataCached.value)); }); + } + if (!verifyCache) return; } diff --git a/src/widgets.js b/src/widgets.js index ac8a88e05281..87ceb9091ba6 100644 --- a/src/widgets.js +++ b/src/widgets.js @@ -673,12 +673,12 @@ angularWidget('ng:include', function(element){ useScope = this.$eval(scopeExp); if (src) { - xhr('GET', src, function(code, response){ + xhr('GET', src, null, function(code, response){ element.html(response); childScope = useScope || createScope(scope); compiler.compile(element)(childScope); scope.$eval(onloadExp); - }); + }, false, true); } else { childScope = null; element.html(''); @@ -1066,10 +1066,10 @@ angularWidget('ng:view', function(element) { } if (src) { - $xhr('GET', src, function(code, response){ + $xhr('GET', src, null, function(code, response){ element.html(response); compiler.compile(element)(childScope); - }); + }, false, true); } else { element.html(''); } diff --git a/test/service/xhr.cacheSpec.js b/test/service/xhr.cacheSpec.js index 82b33b7251b9..0a0140a676e3 100644 --- a/test/service/xhr.cacheSpec.js +++ b/test/service/xhr.cacheSpec.js @@ -107,6 +107,22 @@ describe('$xhr.cache', function() { }); + it('should call callback synchronously when sync flag is on', function() { + $browserXhr.expectGET('/url').respond('+'); + cache('GET', '/url', null, callback, false, true); + expect(log).toEqual(''); //callback hasn't executed + + $browserXhr.flush(); + expect(log).toEqual('"+";'); //callback has executed + + cache('GET', '/url', null, callback, false, true); + expect(log).toEqual('"+";"+";'); //callback has executed + + $browser.defer.flush(); + expect(log).toEqual('"+";"+";'); //callback was not called again any more + }); + + it('should call eval after callbacks for both cache hit and cache miss execute', function() { var eval = this.spyOn(scope, '$eval').andCallThrough(); diff --git a/test/widgetsSpec.js b/test/widgetsSpec.js index 58cc33d86ed7..4fb85c36569e 100644 --- a/test/widgetsSpec.js +++ b/test/widgetsSpec.js @@ -610,7 +610,6 @@ describe("widget", function(){ scope.url = 'myUrl'; scope.$service('$xhr.cache').data.myUrl = {value:'{{name}}'}; scope.$eval(); - scope.$service('$browser').defer.flush(); expect(element.text()).toEqual('misko'); dealoc(scope); }); @@ -623,7 +622,6 @@ describe("widget", function(){ scope.url = 'myUrl'; scope.$service('$xhr.cache').data.myUrl = {value:'{{name}}'}; scope.$eval(); - scope.$service('$browser').defer.flush(); expect(element.text()).toEqual('igor'); @@ -640,7 +638,6 @@ describe("widget", function(){ scope.url = 'myUrl'; scope.$service('$xhr.cache').data.myUrl = {value:'{{c=c+1}}'}; scope.$eval(); - scope.$service('$browser').defer.flush(); // this one should really be just '1', but due to lack of real events things are not working // properly. see discussion at: http://is.gd/ighKk @@ -657,7 +654,6 @@ describe("widget", function(){ scope.url = 'myUrl'; scope.$service('$xhr.cache').data.myUrl = {value:'my partial'}; scope.$eval(); - scope.$service('$browser').defer.flush(); expect(element.text()).toEqual('my partial'); expect(scope.loaded).toBe(true); dealoc(element);