Ben
Ben

Reputation: 16659

Reusable modal in Angular / Ionic

In AngularJS with Ionic, I would like to be able to call one modal from different controllers without having to duplicate the code related to the modal.

Here's how to create a modal (abbreviated from http://learn.ionicframework.com/formulas/making-modals/).

HTML:

<div class="card" ng-controller='MainCtrl' ng-click="openModal()">
    Click here to open the modal
</div>

JS:

app.controller('MainCtrl', function($scope, $ionicModal) 
{
    $ionicModal.fromTemplateUrl('contact-modal.html', {
        scope: $scope,
        animation: 'slide-in-up'
    }).then(function(modal) {
        $scope.modal = modal
    })  

    $scope.openModal = function() {
        $scope.modal.show()
    }

    // functions for this modal
    // ...
})

Now that's all fine an good, but if I want to open the same modal with the same functionality from a different controller, I would have to copy all the code related to it.

How can I abstract this to make my modals reusable and callable from different controllers?

Ideally, I would like each modal to have it's own "controller" (or similar concept), rather than having to put all of its code into the controller of whatever wants to open it.

Upvotes: 7

Views: 6732

Answers (2)

Raj Nandan Sharma
Raj Nandan Sharma

Reputation: 3862

The way i do it is a service

app.service('ModalService', function($ionicModal, $rootScope) {


  var init = function(tpl, $scope) {

    var promise;
    $scope = $scope || $rootScope.$new();

    promise = $ionicModal.fromTemplateUrl(tpl, {
      scope: $scope,
      animation: 'slide-in-up'
    }).then(function(modal) {
      $scope.modal = modal;
      return modal;
    });

    $scope.openModal = function() {
       $scope.modal.show();
     };
     $scope.closeModalService = function() {
       $scope.modal.hide();
        //$scope.modal.remove();
     };
     $scope.$on('$destroy', function() {
       //$scope.modal.remove();
     });

    return promise;
  }

  return {
    init: init
  }

})

How to use it in a controller

app.controller('editMyProfileCtrl', function($scope,ModalService) {

   $scope.openModal = function() {
     ModalService
        .init('my-modal.html', $scope)
        .then(function(modal) {
          modal.show();
      });
  };
  $scope.closeModal = function() {
   $scope.closeModalService();
  };

})

Upvotes: 2

Jacob Carter
Jacob Carter

Reputation: 711

This is a perfect scenario for a Directive.

Directive Code:

app.directive('myPopUp', ['$ionicModal', function($ionicModal) {

    return {
        restrict: 'E',
        scope: {
            externalScope : "="
        }
        replace: true,
        templateUrl: 'path/to/your/template',
        link: function($scope, $element, $attrs) {

            $ionicModal.fromTemplateUrl('contact-modal.html', {
                scope: $scope.externalScope,
                animation: 'slide-in-up'
            }).then(function(modal) {
                $scope.modal = modal
            });

            $scope.externalScope.openModal = function() {
                $scope.modal.show()
            };

        }
    };
}]);

And Your Controller(s):

app.controller('MainCtrl', ['$scope', function($scope) {

    $scope.externalScope = {}

});

Whenever you want to include this in a partial just add:

<my-pop-up externalScope="externalScope"></my-pop-up>

The directive will have access to the controller and vice versa via the externalScope attribute. You can call $scope.externalScope.openModal() from your controller and it will trigger your directive modal to open.

Hope this was helpful.

Upvotes: 4

Related Questions