-
-
Save cef62/0f8ea91e3b0be8f87c24 to your computer and use it in GitHub Desktop.
Decorate ng-strap modal component with an .open() method to support dynamic controller, resolved properties. A promise is returned from open(), resolving when user confirm the modal and rejecting when user cancel the modal.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
'use strict'; | |
angular.module('app.views', []) | |
.controller('MainController', MainController); | |
function MainController($modal) { | |
// --------------------------------- | |
// Open Modal | |
// --------------------------------- | |
this.showModal = function showModal() { | |
var config = { | |
// normal ng-strap | |
animation: 'am-flip-x', | |
placement: 'center', | |
template: 'modal-confirm.tpl.html', | |
keyboard: false, | |
backdrop: 'static', | |
// decorated ng-strap | |
controller: 'ModalConfirmTemplate', | |
controllerAs: 'ctrl', | |
resolve: { | |
provider: function provider() { | |
return { | |
title: 'My Custom Title', | |
content: 'Hello Modal<br />This is a multiline message!' | |
}; | |
}, | |
otherData: function otherData() { | |
return { | |
prop1: 'value1', | |
prop2: 'value2', | |
prop3: 'value3' | |
}; | |
} | |
} | |
}; | |
/* | |
$modal.open() --> return a promise, resolved with a modal object | |
*/ | |
$modal.open(config) | |
.then( | |
function modalOpened(modal) { | |
/* | |
modal has following fields: | |
{ | |
modal: Original $modal response object, | |
promise: promise resolved used close() and cancel() methods, | |
close: close the modal and resolve the promise, accept a single argument to be passed to the promise | |
cancel: cancel the modal and rejet the promise, accept a reason to be passed to the promise | |
} | |
*/ | |
modal.promise | |
.then( | |
function modalAccepted(result) { | |
console.log('modal completed', result); | |
} | |
) | |
.catch( | |
function modalRefused(reason) { | |
console.log('modal canceled: ' + reason); | |
} | |
); | |
} | |
); | |
}; | |
} | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="modal" tabindex="-1" role="dialog"> | |
<div class="modal-dialog profile-delete-modal"> | |
<div class="modal-content text-center"> | |
<div class="modal-body" ng-show="ctrl.content"> | |
<img src="./assets/images/bomb.svg" class="outcomeimgs" /> | |
<h1 class="m-top-0 m-bottom-15 ">{{ctrl.title}} </h1> | |
<p ng-bind-html="ctrl.content"></p> | |
<div> | |
<h3>Other dynamic data</h3> | |
<ul> | |
<li ng-repeat="item in ctrl.otherData">{{item}}</li> | |
</ul> | |
</div> | |
</div> | |
<div class="row m-0 topline"> | |
<div class="row m-0"> | |
<button type="button" class="btn-square-big bg-red col-md-6 small-bold" ng-click="ctrl.cancel('modal dismissed')">No</button> | |
<button type="button" class="btn-square-big bg-black col-md-6 small-bold" ng-click="ctrl.confirm()">Yes</button> | |
</div> | |
</div> | |
</div> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
'use strict'; | |
angular.module('app.modals', [) | |
/* | |
$modals.open() decorates the controller with 2 additional methods: | |
- ctrl.close(result) | |
- ctrl.cancel(reason) | |
*/ | |
.controller('ModalConfirmTemplate', | |
function ModalConfirmTemplate(provider, otherData, userProfile) { | |
// userProfile is a standard injection | |
// provider, otherData are resolved injection | |
this.title = provider.title; | |
this.content = provider.content; | |
this.otherData = otherData; | |
this.confirm = function confirm() { | |
var result = { | |
name: userProfile.first_name + ' ' + userProfile.last_name, | |
email: userProfile.email | |
}; | |
this.close(result); | |
}; | |
} | |
); | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Dependency: underscore.js or lodash | |
(function () { | |
'use strict'; | |
angular.module('app.config') | |
.config( | |
function config($provide) { | |
// Use decorator to add new functionality | |
$provide.decorator('$modal', | |
function modalDecorator($controller, $delegate, $injector, $q, $rootScope) { | |
/* | |
* $modal.open() function | |
* | |
* This function adds new options to `$modal()`. | |
* | |
* New options: | |
* - controller {String|Function} First param of $controller. For string, controllerAs syntax is supported. | |
* - controllerAs {String} The 'as X' part of controllerAs syntax. | |
* - resolve {Object} Like the resolve in ngRoute | |
* | |
* Notes: | |
* -- Use either `controller: myCtrl as vm` or `controllerAs: vm`. Don't use both. | |
* -- Not sure if ngAnnotate supports this. It should since it understands '$modal.open()' in UI Bootstrap | |
*/ | |
function open(config) { | |
var ctrl; | |
var resolvePromises = []; | |
var allDone; | |
var options = _.omit(config, ['controller', 'controllerAs', 'resolve']); // Options to be passed to $modal() | |
var modalScope = options.scope || $rootScope; | |
// Setup controller | |
if (config.controller) { | |
// Resolve | |
if (config.resolve) { | |
resolvePromises = _ | |
.map(config.resolve, | |
function mapValues(resolveFunc) { | |
return $injector.invoke(resolveFunc); | |
} | |
); | |
} | |
allDone = $q.all(resolvePromises) | |
.then( | |
function allResolved(resolves) { | |
var locals = {}; | |
// Assign resolves | |
var iter = 0; | |
_.forEach(config.resolve, | |
function each(resolveFunc, name) { | |
locals[name] = resolves[iter++]; | |
} | |
); | |
// Create new scope | |
modalScope = modalScope.$new(); | |
locals.$scope = modalScope; | |
// Instantiate controller | |
ctrl = $controller(config.controller, locals); | |
// manage controllerAs | |
if (config.controllerAs) { | |
modalScope[config.controllerAs] = ctrl; | |
} | |
} | |
); | |
} else { | |
allDone = $q.when(true); | |
} | |
return allDone.then( | |
function controllerReady() { | |
// Prepare final options | |
_.extend(options, { | |
scope: modalScope | |
}); | |
var modal = $delegate(options); | |
var modalDefer = $q.defer(); | |
// -------------------------------- | |
// add extra methods to controller | |
// -------------------------------- | |
// close resolving promise with return values | |
ctrl.close = function close(result) { | |
modalDefer.resolve(result); | |
modal.hide(); | |
}; | |
// close rejecting promise with specific reason | |
ctrl.cancel = function cancel(reason) { | |
modalDefer.reject(reason); | |
modal.hide(); | |
}; | |
return { | |
modal: modal, | |
promise: modalDefer.promise, | |
close: ctrl.close, | |
cancel: ctrl.cancel | |
}; | |
} | |
); | |
} | |
// Add new open() method to the $modal service | |
$delegate.open = open; | |
return $delegate; | |
} | |
); | |
} | |
); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment