diff options
| author | Igor Minar | 2011-03-30 09:35:59 -0700 | 
|---|---|---|
| committer | Igor Minar | 2011-03-30 15:22:22 -0700 | 
| commit | c06c5a36b108c6ad20776923d75eb6f32ace591b (patch) | |
| tree | e9a7e52b37702f175cb01aaefd0955c06a8d6be8 | |
| parent | 9985104dc0a2f96b1b318a8b662c0806a96f312b (diff) | |
| download | angular.js-c06c5a36b108c6ad20776923d75eb6f32ace591b.tar.bz2 | |
make xhr.cache optionally synchronous
- add `sync` flag xhr.cache
- change ng:include to use the sync flag
- change ng:view to use the sync flag
The end result is that there are fewer repaints in the browser,
which means less "blinking" that user sees.
| -rw-r--r-- | src/service/xhr.cache.js | 11 | ||||
| -rw-r--r-- | src/widgets.js | 8 | ||||
| -rw-r--r-- | test/service/xhr.cacheSpec.js | 16 | ||||
| -rw-r--r-- | test/widgetsSpec.js | 4 | 
4 files changed, 29 insertions, 10 deletions
diff --git a/src/service/xhr.cache.js b/src/service/xhr.cache.js index 284321d7..c6066a5c 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 ac8a88e0..87ceb909 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 82b33b72..0a0140a6 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 58cc33d8..4fb85c36 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);  | 
