Spock Spock - 1 month ago 23
AngularJS Question

How to use Angular-Strap to create a modal with a controller?

I'm struggling to find the right way to use an Angular-Strap modal/aside with a controller.

Yes, the calling code could inject the

$scope
, making it available to the modal. But there are issues with that.

myModal = $modal({
scope: $scope,
template: 'template.html',
show: false,
backdrop: "static",
keyboard: false,
persist: true


});

This will pollute the calling controller with potentially modal-only methods and properties.

I usually use "controllerAs", and therefore don't even have a
$scope
to inject into the modal in the first place!

You could create a new
$scope
and then insert methods into that, but again, that would require injection of
$scope
into the parent controller. Bad bad bad.

If I use
ng-controller
inside the modal template, I can have my controller. But his gives me another problem: now I cannot inject data into the modal controller, and there is no way my calling code can know when the modal is closed and returning data from the modal also becomes a chore (involves a factory just to keep the parent and child controller data synchronized).

I'm really struggling how to make this the best way.

Any ideas?

Cheers

Update

This is how I do it for now:

In my template I make a directive that opens up the modal.

Example:

<my-modal
on-update="ctrl.OnDialogUpdate">
</my-modal>


So basically the directive calls my modal and when the modal closes or wants to return with a result, it calls the method specified in the directive parameter.

This is how the directive could look:

(function() {

'use strict';

angular.module('app').directive('myModal',myModal);

function myModal(){

return {

restrict: 'E',

// The modal callback specified in the directive tag
scope: {
onUpdate: '&?'
},

replace: true,

// This is the template for the directive, not the modal
templateUrl: 'button.html',

controllerAs: 'ctrl',

bindToController: true,

compile: function (element, attrs) {

return function (scope, element, attrs) {

};
},


/*@ngInject*/
controller: function($scope, $log, $aside){

var self = this;

var myDialog = $aside({

// Dialog template
template: 'my-modal.template.html',
show: false,
animation: 'am-fade-and-slide-right',
placement: 'right',
backdrop: true,
html: true,
container: '',
scope: $scope
});


// Opens modal
self.ShowDialog = function(){
myDialog.$promise.then(function() {
myDialog.show();
})
};


// Expose Update() method to the dialog template
$scope.Update = function(){

if(angular.isFunction(self.onUpdate) ) {

self.onUpdate()();
}

}

}
}

}

})();

Answer

Just use the 'controller' option:

$scope.showModal = function() {
  $modal({
    title: 'My Title', 
    content: 'My Content', 
    show: true,
    controller: 'ModalCtrl'
  });
};

Here's a plnkr