Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

feat(modal): add closed promise #4979

Closed
wants to merge 1 commit into from
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
1 change: 1 addition & 0 deletions src/modal/docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ The `open` method returns a modal instance, an object with the following propert
* `dismiss(reason)` - a method that can be used to dismiss a modal, passing a reason
* `result` - a promise that is resolved when a modal is closed and rejected when a modal is dismissed
* `opened` - a promise that is resolved when a modal gets opened after downloading content's template and resolving all variables
* `closed` - a promise that is resolved when a modal is closed and the animation completes
* `rendered` - a promise that is resolved when a modal is rendered.

In addition the scope associated with modal's content is augmented with 2 methods:
Expand Down
9 changes: 8 additions & 1 deletion src/modal/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap'])
}
}

function removeAfterAnimate(domEl, scope, done) {
function removeAfterAnimate(domEl, scope, done, closedDeferred) {
var asyncDeferred;
var asyncPromise = null;
var setIsAsync = function() {
Expand Down Expand Up @@ -336,6 +336,9 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap'])
event: 'leave'
}).start().then(function() {
domEl.remove();
if (closedDeferred) {
closedDeferred.resolve();
}
});

scope.$destroy();
Expand Down Expand Up @@ -392,6 +395,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap'])
openedWindows.add(modalInstance, {
deferred: modal.deferred,
renderDeferred: modal.renderDeferred,
closedDeferred: modal.closedDeferred,
modalScope: modal.scope,
backdrop: modal.backdrop,
keyboard: modal.keyboard,
Expand Down Expand Up @@ -579,12 +583,14 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap'])
$modal.open = function(modalOptions) {
var modalResultDeferred = $q.defer();
var modalOpenedDeferred = $q.defer();
var modalClosedDeferred = $q.defer();
var modalRenderDeferred = $q.defer();

//prepare an instance of a modal to be injected into controllers and returned to a caller
var modalInstance = {
result: modalResultDeferred.promise,
opened: modalOpenedDeferred.promise,
closed: modalClosedDeferred.promise,
rendered: modalRenderDeferred.promise,
close: function (result) {
return $modalStack.close(modalInstance, result);
Expand Down Expand Up @@ -655,6 +661,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap'])
scope: modalScope,
deferred: modalResultDeferred,
renderDeferred: modalRenderDeferred,
closedDeferred: modalClosedDeferred,
content: tplAndVars[0],
animation: modalOptions.animation,
backdrop: modalOptions.backdrop,
Expand Down
14 changes: 14 additions & 0 deletions src/modal/test/modal.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,20 @@ describe('$uibModal', function () {
expect($document).toHaveModalsOpen(0);
});

it('should resolve the closed promise when modal is closed', function() {
var modal = open({template: '<div>Content</div>'});
close(modal, 'closed ok');

expect(modal.closed).toBeResolvedWith(undefined);
});

it('should resolve the closed promise when modal is dismissed', function() {
var modal = open({template: '<div>Content</div>'});
dismiss(modal, 'esc');

expect(modal.closed).toBeResolvedWith(undefined);
});

it('should expose a promise linked to the templateUrl / resolve promises', function() {
var modal = open({template: '<div>Content</div>', resolve: {
ok: function() {return $q.when('ok');}
Expand Down