feat(ngAnimate): let $animate.off() remove all listeners for an element
This commit is contained in:
+6
-1
@@ -326,6 +326,9 @@ var $AnimateProvider = ['$provide', function($provide) {
|
||||
* // remove all the animation event listeners listening for `enter`
|
||||
* $animate.off('enter');
|
||||
*
|
||||
* // remove listeners for all animation events from the container element
|
||||
* $animate.off(container);
|
||||
*
|
||||
* // remove all the animation event listeners listening for `enter` on the given element and its children
|
||||
* $animate.off('enter', container);
|
||||
*
|
||||
@@ -334,7 +337,9 @@ var $AnimateProvider = ['$provide', function($provide) {
|
||||
* $animate.off('enter', container, callback);
|
||||
* ```
|
||||
*
|
||||
* @param {string} event the animation event (e.g. enter, leave, move, addClass, removeClass, etc...)
|
||||
* @param {string|DOMElement} event|container the animation event (e.g. enter, leave, move,
|
||||
* addClass, removeClass, etc...), or the container element. If it is the element, all other
|
||||
* arguments are ignored.
|
||||
* @param {DOMElement=} container the container element the event listener was placed on
|
||||
* @param {Function=} callback the callback function that was registered as the listener
|
||||
*/
|
||||
|
||||
@@ -199,6 +199,15 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
return matches;
|
||||
}
|
||||
|
||||
function filterFromRegistry(list, matchContainer, matchCallback) {
|
||||
var containerNode = extractElementNode(matchContainer);
|
||||
return list.filter(function(entry) {
|
||||
var isMatch = entry.node === containerNode &&
|
||||
(!matchCallback || entry.callback === matchCallback);
|
||||
return !isMatch;
|
||||
});
|
||||
}
|
||||
|
||||
var $animate = {
|
||||
on: function(event, container, callback) {
|
||||
var node = extractElementNode(container);
|
||||
@@ -215,21 +224,21 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
|
||||
},
|
||||
|
||||
off: function(event, container, callback) {
|
||||
if (arguments.length === 1 && !angular.isString(arguments[0])) {
|
||||
container = arguments[0];
|
||||
for (var eventType in callbackRegistry) {
|
||||
callbackRegistry[eventType] = filterFromRegistry(callbackRegistry[eventType], container);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var entries = callbackRegistry[event];
|
||||
if (!entries) return;
|
||||
|
||||
callbackRegistry[event] = arguments.length === 1
|
||||
? null
|
||||
: filterFromRegistry(entries, container, callback);
|
||||
|
||||
function filterFromRegistry(list, matchContainer, matchCallback) {
|
||||
var containerNode = extractElementNode(matchContainer);
|
||||
return list.filter(function(entry) {
|
||||
var isMatch = entry.node === containerNode &&
|
||||
(!matchCallback || entry.callback === matchCallback);
|
||||
return !isMatch;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
pin: function(element, parentElement) {
|
||||
|
||||
@@ -1896,6 +1896,68 @@ describe("animations", function() {
|
||||
expect(count).toBe(3);
|
||||
}));
|
||||
|
||||
it('should remove all event listeners for an element when $animate.off(element) is called',
|
||||
inject(function($animate, $rootScope, $rootElement, $document, $$rAF) {
|
||||
|
||||
element = jqLite('<div></div>');
|
||||
var otherElement = jqLite('<div></div>');
|
||||
$rootElement.append(otherElement);
|
||||
|
||||
var count = 0;
|
||||
var runner;
|
||||
$animate.on('enter', element, counter);
|
||||
$animate.on('leave', element, counter);
|
||||
$animate.on('addClass', element, counter);
|
||||
$animate.on('addClass', otherElement, counter);
|
||||
|
||||
function counter(element, phase) {
|
||||
count++;
|
||||
}
|
||||
|
||||
runner = $animate.enter(element, $rootElement);
|
||||
$rootScope.$digest();
|
||||
$animate.flush();
|
||||
runner.end();
|
||||
|
||||
runner = $animate.addClass(element, 'blue');
|
||||
$rootScope.$digest();
|
||||
$animate.flush();
|
||||
|
||||
runner.end();
|
||||
$$rAF.flush();
|
||||
|
||||
expect(count).toBe(4);
|
||||
|
||||
$animate.off(element);
|
||||
|
||||
runner = $animate.enter(element, $rootElement);
|
||||
$animate.flush();
|
||||
expect(capturedAnimation[1]).toBe('enter');
|
||||
runner.end();
|
||||
|
||||
runner = $animate.addClass(element, 'red');
|
||||
$animate.flush();
|
||||
expect(capturedAnimation[1]).toBe('addClass');
|
||||
runner.end();
|
||||
|
||||
runner = $animate.leave(element);
|
||||
$animate.flush();
|
||||
expect(capturedAnimation[1]).toBe('leave');
|
||||
runner.end();
|
||||
|
||||
// Try to flush all remaining callbacks
|
||||
expect(function() {
|
||||
$$rAF.flush();
|
||||
}).toThrowError('No rAF callbacks present');
|
||||
|
||||
expect(count).toBe(4);
|
||||
|
||||
// Check that other elements' event listeners are not affected
|
||||
$animate.addClass(otherElement, 'green');
|
||||
$animate.flush();
|
||||
expect(count).toBe(5);
|
||||
}));
|
||||
|
||||
it('should fire a `start` callback when the animation starts with the matching element',
|
||||
inject(function($animate, $rootScope, $rootElement, $document) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user