mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-20 00:10:26 +00:00
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.
This commit is contained in:
parent
9985104dc0
commit
c06c5a36b1
4 changed files with 29 additions and 10 deletions
|
|
@ -20,10 +20,11 @@
|
||||||
* @param {boolean=} [verifyCache=false] If `true` then a result is immediately returned from cache
|
* @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
|
* (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.
|
* 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){
|
angularServiceInject('$xhr.cache', function($xhr, $defer, $log){
|
||||||
var inflight = {}, self = this;
|
var inflight = {}, self = this;
|
||||||
function cache(method, url, post, callback, verifyCache){
|
function cache(method, url, post, callback, verifyCache, sync){
|
||||||
if (isFunction(post)) {
|
if (isFunction(post)) {
|
||||||
callback = post;
|
callback = post;
|
||||||
post = null;
|
post = null;
|
||||||
|
|
@ -31,7 +32,13 @@ angularServiceInject('$xhr.cache', function($xhr, $defer, $log){
|
||||||
if (method == 'GET') {
|
if (method == 'GET') {
|
||||||
var data, dataCached;
|
var data, dataCached;
|
||||||
if (dataCached = cache.data[url]) {
|
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)
|
if (!verifyCache)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -673,12 +673,12 @@ angularWidget('ng:include', function(element){
|
||||||
useScope = this.$eval(scopeExp);
|
useScope = this.$eval(scopeExp);
|
||||||
|
|
||||||
if (src) {
|
if (src) {
|
||||||
xhr('GET', src, function(code, response){
|
xhr('GET', src, null, function(code, response){
|
||||||
element.html(response);
|
element.html(response);
|
||||||
childScope = useScope || createScope(scope);
|
childScope = useScope || createScope(scope);
|
||||||
compiler.compile(element)(childScope);
|
compiler.compile(element)(childScope);
|
||||||
scope.$eval(onloadExp);
|
scope.$eval(onloadExp);
|
||||||
});
|
}, false, true);
|
||||||
} else {
|
} else {
|
||||||
childScope = null;
|
childScope = null;
|
||||||
element.html('');
|
element.html('');
|
||||||
|
|
@ -1066,10 +1066,10 @@ angularWidget('ng:view', function(element) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src) {
|
if (src) {
|
||||||
$xhr('GET', src, function(code, response){
|
$xhr('GET', src, null, function(code, response){
|
||||||
element.html(response);
|
element.html(response);
|
||||||
compiler.compile(element)(childScope);
|
compiler.compile(element)(childScope);
|
||||||
});
|
}, false, true);
|
||||||
} else {
|
} else {
|
||||||
element.html('');
|
element.html('');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
it('should call eval after callbacks for both cache hit and cache miss execute', function() {
|
||||||
var eval = this.spyOn(scope, '$eval').andCallThrough();
|
var eval = this.spyOn(scope, '$eval').andCallThrough();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -610,7 +610,6 @@ describe("widget", function(){
|
||||||
scope.url = 'myUrl';
|
scope.url = 'myUrl';
|
||||||
scope.$service('$xhr.cache').data.myUrl = {value:'{{name}}'};
|
scope.$service('$xhr.cache').data.myUrl = {value:'{{name}}'};
|
||||||
scope.$eval();
|
scope.$eval();
|
||||||
scope.$service('$browser').defer.flush();
|
|
||||||
expect(element.text()).toEqual('misko');
|
expect(element.text()).toEqual('misko');
|
||||||
dealoc(scope);
|
dealoc(scope);
|
||||||
});
|
});
|
||||||
|
|
@ -623,7 +622,6 @@ describe("widget", function(){
|
||||||
scope.url = 'myUrl';
|
scope.url = 'myUrl';
|
||||||
scope.$service('$xhr.cache').data.myUrl = {value:'{{name}}'};
|
scope.$service('$xhr.cache').data.myUrl = {value:'{{name}}'};
|
||||||
scope.$eval();
|
scope.$eval();
|
||||||
scope.$service('$browser').defer.flush();
|
|
||||||
|
|
||||||
expect(element.text()).toEqual('igor');
|
expect(element.text()).toEqual('igor');
|
||||||
|
|
||||||
|
|
@ -640,7 +638,6 @@ describe("widget", function(){
|
||||||
scope.url = 'myUrl';
|
scope.url = 'myUrl';
|
||||||
scope.$service('$xhr.cache').data.myUrl = {value:'{{c=c+1}}'};
|
scope.$service('$xhr.cache').data.myUrl = {value:'{{c=c+1}}'};
|
||||||
scope.$eval();
|
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
|
// 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
|
// properly. see discussion at: http://is.gd/ighKk
|
||||||
|
|
@ -657,7 +654,6 @@ describe("widget", function(){
|
||||||
scope.url = 'myUrl';
|
scope.url = 'myUrl';
|
||||||
scope.$service('$xhr.cache').data.myUrl = {value:'my partial'};
|
scope.$service('$xhr.cache').data.myUrl = {value:'my partial'};
|
||||||
scope.$eval();
|
scope.$eval();
|
||||||
scope.$service('$browser').defer.flush();
|
|
||||||
expect(element.text()).toEqual('my partial');
|
expect(element.text()).toEqual('my partial');
|
||||||
expect(scope.loaded).toBe(true);
|
expect(scope.loaded).toBe(true);
|
||||||
dealoc(element);
|
dealoc(element);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue