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

Fixed issue with dialog double opening and inability to close second dialog. #5157

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/dialog/dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function MdDialogDirective($$rAF, $mdTheming, $mdDialog) {
}

scope.$on('$destroy', function() {
$mdDialog.destroy();
$mdDialog.destroyInstance(element[0].parentNode);
});

/**
Expand Down
60 changes: 59 additions & 1 deletion src/components/dialog/dialog.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,65 @@ describe('$mdDialog', function() {
expect(parent[0].querySelectorAll('md-dialog.two').length).toBe(1);
}));

it('should hide dialog', inject(function($mdDialog, $rootScope, $animate) {
var parent = angular.element('<div>');
$mdDialog.show({
template: '<md-dialog class="one">',
parent: parent
});
runAnimation();

$mdDialog.hide();
runAnimation();

expect(parent[0].querySelectorAll('md-dialog.one').length).toBe(0);
}));

it('should allow opening new dialog after existing without corruption', inject(function($mdDialog, $rootScope, $animate) {
var parent = angular.element('<div>');
$mdDialog.show({
template: '<md-dialog class="one">',
parent: parent
});
runAnimation();
$mdDialog.hide();
runAnimation();

$mdDialog.show({
template: '<md-dialog class="two">',
parent: parent
});
runAnimation();
$mdDialog.hide();
runAnimation();

expect(parent[0].querySelectorAll('md-dialog.one').length).toBe(0);
expect(parent[0].querySelectorAll('md-dialog.two').length).toBe(0);
}));

it('should allow opening new dialog from existing without corruption', inject(function($mdDialog, $rootScope, $animate) {
var parent = angular.element('<div>');
$mdDialog.show({
template: '<md-dialog class="one">',
parent: parent
});
runAnimation();

$mdDialog.show({
template: '<md-dialog class="two">',
parent: parent
});
//First run is for the old dialog being hidden.
runAnimation();
//Second run is for the new dialog being shown.
runAnimation();
$mdDialog.hide();
runAnimation();

expect(parent[0].querySelectorAll('md-dialog.one').length).toBe(0);
expect(parent[0].querySelectorAll('md-dialog.two').length).toBe(0);
}));

it('should have the dialog role', inject(function($mdDialog, $rootScope) {
var template = '<md-dialog>Hello</md-dialog>';
var parent = angular.element('<div>');
Expand Down Expand Up @@ -1117,4 +1176,3 @@ describe('$mdDialog with custom interpolation symbols', function() {
expect(buttons.eq(1).text()).toBe('OK');
}));
});

31 changes: 29 additions & 2 deletions src/core/services/interimElement/interimElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ function InterimElementProvider() {

// Special internal method to destroy an interim element without animations
// used when navigation changes causes a $scope.$destroy() action
destroy : destroyInterimElement
destroy : destroyInterimElement,
destroyInstance : detroyInterimElementInstance
};


Expand Down Expand Up @@ -222,6 +223,10 @@ function InterimElementProvider() {
return interimElementService.destroy(opts);
}

function detroyInterimElementInstance(opts) {
return interimElementService.destroyInstance(opts);
}

/**
* Helper to call $injector.invoke with a local of the factory name for
* this provider.
Expand Down Expand Up @@ -262,7 +267,8 @@ function InterimElementProvider() {
show: show,
hide: hide,
cancel: cancel,
destroy : destroy
destroy : destroy,
destroyInstance: destroyInstance
};

/*
Expand Down Expand Up @@ -378,6 +384,27 @@ function InterimElementProvider() {
$q.when(SHOW_CANCELLED);
}

/*
* Special method to quick-remove a specific interim element without animations
*
* @param element A DOM element, to which the interim element instance we want
* to destroy is attached.
*/
function destroyInstance(element) {

if (element) {
//Try to find the interim element in the stack which corresponds to the supplied DOM element.
//This function might be called when the element already has been removed, in which
//case we won't find any matches. That's ok.
var filtered = stack.filter(function(entry) { return entry.options.element[0] === element;});
if (filtered.length > 0) {
var interim = filtered[0];
stack.splice(stack.indexOf(interim), 1);
return interim.remove(SHOW_CANCELLED, false, {'$destroy':true});
}
}
return $q.when(SHOW_CANCELLED);
}

/*
* Internal Interim Element Object
Expand Down