Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit 93c2917

Browse files
crisbetokara
authored andcommitted
fix(select): unable to reopen if element was destroyed while closing (#10556)
Fixes #10453.
1 parent f8deb0e commit 93c2917

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

src/components/select/select.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,33 +1112,43 @@ function SelectProvider($$interimElementProvider) {
11121112
* Interim-element onRemove logic....
11131113
*/
11141114
function onRemove(scope, element, opts) {
1115+
var animationRunner = null;
1116+
var destroyListener = scope.$on('$destroy', function() {
1117+
// Listen for the case where the element was destroyed while there was an
1118+
// ongoing close animation. If this happens, we need to end the animation
1119+
// manually.
1120+
animationRunner.end();
1121+
});
1122+
11151123
opts = opts || { };
11161124
opts.cleanupInteraction();
11171125
opts.cleanupResizing();
11181126
opts.hideBackdrop();
11191127

11201128
// For navigation $destroy events, do a quick, non-animated removal,
11211129
// but for normal closes (from clicks, etc) animate the removal
1122-
1123-
return (opts.$destroy === true) ? cleanElement() : animateRemoval().then( cleanElement );
1130+
return (opts.$destroy === true) ? cleanElement() : animateRemoval().then(cleanElement);
11241131

11251132
/**
11261133
* For normal closes (eg clicks), animate the removal.
11271134
* For forced closes (like $destroy events from navigation),
11281135
* skip the animations
11291136
*/
11301137
function animateRemoval() {
1131-
return $animateCss(element, {addClass: 'md-leave'}).start();
1138+
animationRunner = $animateCss(element, {addClass: 'md-leave'});
1139+
return animationRunner.start();
11321140
}
11331141

11341142
/**
11351143
* Restore the element to a closed state
11361144
*/
11371145
function cleanElement() {
1146+
destroyListener();
11381147

1139-
element.removeClass('md-active');
1140-
element.attr('aria-hidden', 'true');
1141-
element[0].style.display = 'none';
1148+
element
1149+
.removeClass('md-active')
1150+
.attr('aria-hidden', 'true')
1151+
.css('display', 'none');
11421152

11431153
announceClosed(opts);
11441154

src/components/select/select.spec.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,27 @@ describe('<md-select>', function() {
271271
expect(label.textContent).toBe('4');
272272
});
273273

274+
it('it should be able to reopen if the element was destroyed while the close ' +
275+
'animation is running', function() {
276+
$rootScope.showSelect = true;
277+
278+
var container = setupSelect('ng-model="val" ng-if="showSelect"', [1, 2, 3]);
279+
var select = container.find('md-select');
280+
281+
openSelect(select);
282+
expectSelectOpen(select);
283+
284+
clickOption(select, 0);
285+
$rootScope.$apply('showSelect = false');
286+
expectSelectClosed(select);
287+
288+
$rootScope.$apply('showSelect = true');
289+
select = container.find('md-select');
290+
291+
openSelect(select);
292+
expectSelectOpen(select);
293+
});
294+
274295
describe('when required', function() {
275296
it('allows 0 as a valid default value', function() {
276297
$rootScope.model = 0;

0 commit comments

Comments
 (0)