mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-04-27 19:13:55 +08:00
pref($animate): group all asynchronous requests into one shared buffer
This commit is contained in:
committed by
Igor Minar
parent
b7e4e92014
commit
f288b8f010
@@ -268,6 +268,20 @@ angular.module('ngAnimate', ['ng'])
|
||||
};
|
||||
}])
|
||||
|
||||
.factory('$$asyncQueueBuffer', ['$timeout', function($timeout) {
|
||||
var timer, queue = [];
|
||||
return function(fn) {
|
||||
$timeout.cancel(timer);
|
||||
queue.push(fn);
|
||||
timer = $timeout(function() {
|
||||
for(var i = 0; i < queue.length; i++) {
|
||||
queue[i]();
|
||||
}
|
||||
queue = [];
|
||||
}, 0, false);
|
||||
};
|
||||
}])
|
||||
|
||||
.config(['$provide', '$animateProvider', function($provide, $animateProvider) {
|
||||
var noop = angular.noop;
|
||||
var forEach = angular.forEach;
|
||||
@@ -291,9 +305,10 @@ angular.module('ngAnimate', ['ng'])
|
||||
return extractElementNode(elm1) == extractElementNode(elm2);
|
||||
}
|
||||
|
||||
$provide.decorator('$animate', ['$delegate', '$injector', '$sniffer', '$rootElement', '$timeout', '$rootScope', '$document',
|
||||
function($delegate, $injector, $sniffer, $rootElement, $timeout, $rootScope, $document) {
|
||||
$provide.decorator('$animate', ['$delegate', '$injector', '$sniffer', '$rootElement', '$$asyncQueueBuffer', '$rootScope', '$document',
|
||||
function($delegate, $injector, $sniffer, $rootElement, $$asyncQueueBuffer, $rootScope, $document) {
|
||||
|
||||
var globalAnimationCounter = 0;
|
||||
$rootElement.data(NG_ANIMATE_STATE, rootAnimateState);
|
||||
|
||||
// disable animations during bootstrap, but once we bootstrapped, wait again
|
||||
@@ -315,10 +330,6 @@ angular.module('ngAnimate', ['ng'])
|
||||
return classNameFilter.test(className);
|
||||
};
|
||||
|
||||
function async(fn) {
|
||||
return $timeout(fn, 0, false);
|
||||
}
|
||||
|
||||
function lookup(name) {
|
||||
if (name) {
|
||||
var matches = [],
|
||||
@@ -685,7 +696,6 @@ angular.module('ngAnimate', ['ng'])
|
||||
if(ngAnimateState.running) {
|
||||
//if an animation is currently running on the element then lets take the steps
|
||||
//to cancel that animation and fire any required callbacks
|
||||
$timeout.cancel(ngAnimateState.closeAnimationTimeout);
|
||||
cleanup(element);
|
||||
cancelAnimations(ngAnimateState.animations);
|
||||
|
||||
@@ -736,12 +746,15 @@ angular.module('ngAnimate', ['ng'])
|
||||
//parent animations to find and cancel child animations when needed
|
||||
element.addClass(NG_ANIMATE_CLASS_NAME);
|
||||
|
||||
var localAnimationCount = globalAnimationCounter++;
|
||||
|
||||
element.data(NG_ANIMATE_STATE, {
|
||||
running:true,
|
||||
event:animationEvent,
|
||||
className:className,
|
||||
structural:!isClassBased,
|
||||
animations:animations,
|
||||
index:localAnimationCount,
|
||||
done:onBeforeAnimationsComplete
|
||||
});
|
||||
|
||||
@@ -816,19 +829,19 @@ angular.module('ngAnimate', ['ng'])
|
||||
}
|
||||
|
||||
function fireBeforeCallbackAsync() {
|
||||
async(function() {
|
||||
$$asyncQueueBuffer(function() {
|
||||
fireDOMCallback('before');
|
||||
});
|
||||
}
|
||||
|
||||
function fireAfterCallbackAsync() {
|
||||
async(function() {
|
||||
$$asyncQueueBuffer(function() {
|
||||
fireDOMCallback('after');
|
||||
});
|
||||
}
|
||||
|
||||
function fireDoneCallbackAsync() {
|
||||
async(function() {
|
||||
$$asyncQueueBuffer(function() {
|
||||
fireDOMCallback('close');
|
||||
doneCallback && doneCallback();
|
||||
});
|
||||
@@ -855,8 +868,11 @@ angular.module('ngAnimate', ['ng'])
|
||||
if(isClassBased) {
|
||||
cleanup(element);
|
||||
} else {
|
||||
data.closeAnimationTimeout = async(function() {
|
||||
cleanup(element);
|
||||
$$asyncQueueBuffer(function() {
|
||||
var data = element.data(NG_ANIMATE_STATE) || {};
|
||||
if(localAnimationCount == data.index) {
|
||||
cleanup(element);
|
||||
}
|
||||
});
|
||||
element.data(NG_ANIMATE_STATE, data);
|
||||
}
|
||||
|
||||
@@ -2563,8 +2563,9 @@ describe("ngAnimate", function() {
|
||||
});
|
||||
|
||||
|
||||
it("should disable all child animations on structural animations until the post animation timeout has passed", function() {
|
||||
var intercepted;
|
||||
it("should disable all child animations on structural animations until the post animation" +
|
||||
"timeout has passed as well as all structural animations", function() {
|
||||
var intercepted, continueAnimation;
|
||||
module(function($animateProvider) {
|
||||
$animateProvider.register('.animated', function() {
|
||||
return {
|
||||
@@ -2578,7 +2579,10 @@ describe("ngAnimate", function() {
|
||||
function ani(type) {
|
||||
return function(element, className, done) {
|
||||
intercepted = type;
|
||||
(done || className)();
|
||||
continueAnimation = function() {
|
||||
continueAnimation = angular.noop;
|
||||
(done || className)();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -2595,26 +2599,45 @@ describe("ngAnimate", function() {
|
||||
var child2 = $compile('<div class="child2 animated">...</div>')($rootScope);
|
||||
var container = $compile('<div class="container">...</div>')($rootScope);
|
||||
|
||||
jqLite($document[0].body).append($rootElement);
|
||||
var body = angular.element($document[0].body);
|
||||
body.append($rootElement);
|
||||
$rootElement.append(container);
|
||||
element.append(child1);
|
||||
element.append(child2);
|
||||
|
||||
$animate.enter(element, container);
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(intercepted).toBe('enter');
|
||||
continueAnimation();
|
||||
|
||||
$animate.addClass(child1, 'test');
|
||||
expect(child1.hasClass('test')).toBe(true);
|
||||
|
||||
expect(element.children().length).toBe(2);
|
||||
|
||||
expect(intercepted).toBe('enter');
|
||||
$animate.leave(child1);
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(element.children().length).toBe(1);
|
||||
|
||||
expect(intercepted).toBe('enter');
|
||||
|
||||
$animate.move(element, null, container);
|
||||
$rootScope.$digest();
|
||||
|
||||
expect(intercepted).toBe('move');
|
||||
|
||||
$animate.addClass(child1, 'test');
|
||||
expect(child1.hasClass('test')).toBe(true);
|
||||
|
||||
expect(intercepted).toBe('move');
|
||||
$animate.leave(child1);
|
||||
$rootScope.$digest();
|
||||
//flush the enter reflow
|
||||
$timeout.flush();
|
||||
|
||||
$animate.addClass(child2, 'testing');
|
||||
expect(intercepted).toBe('move');
|
||||
|
||||
//reflow has passed
|
||||
continueAnimation();
|
||||
|
||||
//flush the move reflow
|
||||
$timeout.flush();
|
||||
|
||||
$animate.leave(child2);
|
||||
|
||||
Reference in New Issue
Block a user