Search code examples
angularjsangularjs-scopeangular-ui-bootstrapangularjs-controllerangular-bootstrap

Firing event from dynamically opened controller to parent controller in Angular js


I am developing an Web Application using Angular JS. I am new to Angular JS. in my app I am using bootstrap.ui JS for Angular js. But I am having a problem with bootstrap modal controller. I open the bootstrap modal with new controller instance. Then I want to fire event back to parent controller when a button of modal is pressed.

I open Bootstrap modal when a button is clicked like below in a controller

var app = angular.module('memeApp',['ngRoute','ui.bootstrap','blockUI','ngFileUpload'],function($interpolateProvider) {
        $interpolateProvider.startSymbol('<%');
        $interpolateProvider.endSymbol('%>');
    });


app.controller('DeleteConfirmModalController', ['$scope','$modalInstance','data',function ($scope, $modalInstance,data) {
    $scope.closeDeleteConfirmModal = function () {
        $modalInstance.dismiss('cancel');
    };

    $scope.deleteData = function()
    {
       //I want to call deleted function of DefaultController that opened current controller.
    }
}]);

app.controller('DefaultController', ['$scope', 'Upload', '$timeout', '$http','$modal', function ($scope, Upload, $timeout , $http, $modal) {

  $scope.deleted = function(param)
  {
      alert('deleted')
  }    

  $scope.deleteTemplate = function(id,url)
  {
    var modalInstance = $modal.open({
            controller: 'DeleteConfirmModalController',
            templateUrl: $scope.deleteConfirmModalUrl,
            resolve: {
                data: function () {
                    return { id: id, url: url };
                }
            }
        });
  }

}]);

Let me explain my code above. When a user click a button in DefaultController, deleteTemplate function will be called. So that function open bootstrap modal creating new instance of DeleteConfirmModalController. When user click the delete button of bootstrap modal, deleteData function of modal controller will be called.

So I commented what I want to do inside that function. I want to call deleted function inside DefaultController. How can I call that function of parent controller from modal controller?


Solution

  • You can do so easily by passing the function you want to run as a callback to the modal.

    vm.deleteData = function() {
       // do something
    }
    

    Then pass to

    var modalInstance = $uibModal.open({
      animation: true,
      templateUrl: 'vm.deleteConfirmModalUrl',
      controller: 'DeleteConfirmModalController',
      controllerAs: 'vm',
      resolve: {
        deletedCallback: function() {
          return vm.deleted; // notice that I am passing a reference of `deleted` function
        }
      }
    });
    

    Then, inside the modal controller I wire an invocation to this callback function by a button click

    .controller('ModalInstanceCtrl', function ($uibModalInstance, deletedCallback) {
    
        // this will run on an ng-click
        vm.runDeleted = function() {
            if (angular.isFunction(deletedCallback)) {
              deletedCallback("me");
            }
        }
        ...
    }
    

    I use angular.isFunction to test if the reference I passed to the modal controller is indeed of that of a function, and if it is, I run it, and I pass some value (in this case the string me) into the callback. This code will run on the DeleteConfirmModalController controller.

    Example plunk