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

Commit

Permalink
feat(modal): add pluggable resolve support
Browse files Browse the repository at this point in the history
- Adds support for pluggable resolvers, namely for supporting UI Router's resolve handling

Closes #3405
Closes #5078
  • Loading branch information
wesleycho committed Dec 16, 2015
1 parent fd59913 commit 2635f0d
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 20 deletions.
4 changes: 4 additions & 0 deletions src/modal/docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,7 @@ Events fired:
* `modal.closing` -
This event is broadcast to the modal scope before the modal closes. If the listener calls preventDefault() on the event, then the modal will remain open.
Also, the `$close` and `$dismiss` methods returns true if the event was executed. This event also includes a parameter for the result/reason and a boolean that indicates whether the modal is being closed (true) or dismissed.

##### UI Router resolves

If one wants to have the modal resolve using [UI Router's](https://github.com/angular-ui/ui-router) pre-1.0 resolve mechanism, one can call `$uibResolve.setResolver('$resolve')` in the configuration phase of the application. One can also provide a custom resolver as well, as long as the signature conforms to UI Router's [$resolve](http://angular-ui.github.io/ui-router/site/#/api/ui.router.util.$resolve).
71 changes: 51 additions & 20 deletions src/modal/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,52 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap'])
};
})

/**
* Pluggable resolve mechanism for the modal resolve resolution
* Supports UI Router's $resolve service
*/
.provider('$uibResolve', function() {
var resolve = this;
this.resolver = null;

this.setResolver = function(resolver) {
this.resolver = resolver;
};

this.$get = ['$injector', '$q', function($injector, $q) {
var resolver = resolve.resolver ? $injector.get(resolve.resolver) : null;
return {
resolve: function(invocables, locals, parent, self) {
if (resolver) {
return resolver.resolve(invocables, locals, parent, self);
}

var promises = [];

angular.forEach(invocables, function(value) {
if (angular.isFunction(value) || angular.isArray(value)) {
promises.push($q.resolve($injector.invoke(value)));
} else if (angular.isString(value)) {
promises.push($q.resolve($injector.get(value)));
} else {
promises.push($q.resolve(value));
}
});

return $q.all(promises).then(function(resolves) {
var resolveObj = {};
var resolveIter = 0;
angular.forEach(invocables, function(value, key) {
resolveObj[key] = resolves[resolveIter++];
});

return resolveObj;
});
}
};
}];
})

/**
* A helper directive for the $modal service. It creates a backdrop element.
*/
Expand Down Expand Up @@ -542,8 +588,8 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap'])
backdrop: true, //can also be false or 'static'
keyboard: true
},
$get: ['$injector', '$rootScope', '$q', '$document', '$templateRequest', '$controller', '$uibModalStack',
function ($injector, $rootScope, $q, $document, $templateRequest, $controller, $modalStack) {
$get: ['$rootScope', '$q', '$document', '$templateRequest', '$controller', '$uibResolve', '$uibModalStack',
function ($rootScope, $q, $document, $templateRequest, $controller, $uibResolve, $modalStack) {
var $modal = {};

function getTemplatePromise(options) {
Expand All @@ -552,20 +598,6 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap'])
options.templateUrl() : options.templateUrl);
}

function getResolvePromises(resolves) {
var promisesArr = [];
angular.forEach(resolves, function(value) {
if (angular.isFunction(value) || angular.isArray(value)) {
promisesArr.push($q.when($injector.invoke(value)));
} else if (angular.isString(value)) {
promisesArr.push($q.when($injector.get(value)));
} else {
promisesArr.push($q.when(value));
}
});
return promisesArr;
}

var promiseChain = null;
$modal.getPromiseChain = function() {
return promiseChain;
Expand Down Expand Up @@ -602,7 +634,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap'])
}

var templateAndResolvePromise =
$q.all([getTemplatePromise(modalOptions)].concat(getResolvePromises(modalOptions.resolve)));
$q.all([getTemplatePromise(modalOptions), $uibResolve.resolve(modalOptions.resolve, {}, null, null)]);

function resolveWithTemplate() {
return templateAndResolvePromise;
Expand All @@ -629,14 +661,13 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap'])
});

var ctrlInstance, ctrlLocals = {};
var resolveIter = 1;

//controllers
if (modalOptions.controller) {
ctrlLocals.$scope = modalScope;
ctrlLocals.$uibModalInstance = modalInstance;
angular.forEach(modalOptions.resolve, function(value, key) {
ctrlLocals[key] = tplAndVars[resolveIter++];
angular.forEach(tplAndVars[1], function(value, key) {
ctrlLocals[key] = value;
});

ctrlInstance = $controller(modalOptions.controller, ctrlLocals);
Expand Down
49 changes: 49 additions & 0 deletions src/modal/test/modal.spec.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,51 @@
describe('$uibResolve', function() {
beforeEach(module('ui.bootstrap.modal'));

it('should resolve invocables and return promise with object of resolutions', function() {
module(function($provide) {
$provide.factory('bar', function() {
return 'bar';
});
});

inject(function($q, $rootScope, $uibResolve) {
$uibResolve.resolve({
foo: 'bar',
bar: $q.resolve('baz'),
baz: function() {
return 'boo';
}
}).then(function(resolves) {
expect(resolves).toEqual({
foo: 'bar',
bar: 'baz',
baz: 'boo'
});
});

$rootScope.$digest();
});
});

describe('with custom resolver', function() {
beforeEach(module(function($provide, $uibResolveProvider) {
$provide.factory('$resolve', function() {
return {
resolve: jasmine.createSpy()
};
});

$uibResolveProvider.setResolver('$resolve');
}));

it('should call $resolve.resolve', inject(function($uibResolve, $resolve) {
$uibResolve.resolve({foo: 'bar'}, {}, null, null);

expect($resolve.resolve).toHaveBeenCalledWith({foo: 'bar'}, {}, null, null);
}));
});
});

describe('$uibModal', function () {
var $animate, $controllerProvider, $rootScope, $document, $compile, $templateCache, $timeout, $q;
var $uibModal, $uibModalStack, $uibModalProvider;
Expand Down Expand Up @@ -1430,3 +1478,4 @@ describe('$uibModal', function () {
});
});
});

0 comments on commit 2635f0d

Please sign in to comment.