aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgor Minar2011-03-30 09:35:59 -0700
committerIgor Minar2011-03-30 15:22:22 -0700
commitc06c5a36b108c6ad20776923d75eb6f32ace591b (patch)
treee9a7e52b37702f175cb01aaefd0955c06a8d6be8
parent9985104dc0a2f96b1b318a8b662c0806a96f312b (diff)
downloadangular.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.js11
-rw-r--r--src/widgets.js8
-rw-r--r--test/service/xhr.cacheSpec.js16
-rw-r--r--test/widgetsSpec.js4
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);