Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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()();
                }

            }

        }
    }

}

})();
like image 732
Spock Avatar asked Oct 20 '22 15:10

Spock


1 Answers

Just use the 'controller' option:

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

Here's a plnkr

like image 79
o4ohel Avatar answered Oct 22 '22 21:10

o4ohel