var app = angular.module('plunker', ['modalModule']);

app.controller('MainCtrl', function($scope, $modal) {
  $scope.name = 'World';
  $scope.openDalog = function(){
    var res = $modal.open({
      component:'modalComponent',
      resolve:{
        name:function(){ 
          return $scope.name; 
        }
      }
    })
    
    res.then(val=>{
      alert(val)
    })
  }
});
<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.5.x" src="https://code.angularjs.org/1.5.8/angular.js" data-semver="1.5.8"></script>
    <script src="modalModule.js"></script>
    <script src="app.js"></script>
    <script src="modalComponent.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <h1 style="text-align:center">Modal Service</h1>
    <p>
      Assuming that you have some component defined in your project
      <pre>
        
        &lt;modal-component&gt; &lt;/modal-component&gt;
      </pre>  
      You can use $modal service following way:
      <pre>
        
        app.controller('MainCtrl', function($scope, $modal) {
          $scope.name = 'World';
          
          $scope.openDalog = function(){
            $modal.open({
              component:'modalComponent',
              resolve:{ //if you need to pass something to module's scope
                name:function(){ 
                  return $scope.name; 
                }
              }
            })
          }
        });
        
      </pre>  
      
    </p>
    
    
    <button ng-click="openDalog()">click here to see modal in action</button>
    
  </body>

</html>
/* Put your css in here */
.backdrop{
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1040;
    overflow: hidden;
    outline: 0;
    background:grey;
    opacity:0.5;
}
.modal-window{
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1050;
    overflow: hidden;
    outline: 0;
  
} 
.modal{
    position:relative;
    width: 600px;
    height:300px;
    margin: 30px auto;
    background:white;
}


/*===========*/
pre{
  background:#EFEFEF;
}

angular.module('modalModule',[])
.factory('$modal',function($document, $rootScope, $compile, $q){
  var SNAKE_CASE_REGEXP = /[A-Z]/g;
  
  function snake_case(name) {
        var separator = '-';
        return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {
          console.log('koko'+letter.toLowerCase())
          return (pos ? separator : '') + letter.toLowerCase();
        });
  }
  function open(options) { 
    this.promise = $q.defer();
    this.modalWindowElScope = $rootScope.$new();
    
    var toTransclude = '';
    if(options.template){
      toTransclude = options.template;
    } else if (options.component) {
      
      this.modalWindowElScope.close = function(val){
        this.close(val)
      }.bind(this)
      
      if (options.resolve) {this.modalWindowElScope.resolve = options.resolve;}
      console.log('uuu',snake_case(options.component))
      toTransclude = `<${snake_case(options.component)} resolve="resolve" close="close(val)"></${snake_case(options.component)}>`; 
    }
    var str = `<div class="modal-window" my-modal-window>${toTransclude}</div>`;
    this.modalWindowEl = $compile(str)(this.modalWindowElScope);
    
    this.backdropElScope = $rootScope.$new();
    this.backdropEl = $compile('<div class="backdrop" my-modal-backdrop></div>')(this.backdropElScope);
    
    angular.element($document[0].body)
    .append(this.modalWindowEl)
    .append(this.backdropEl)
    
    return this.promise.promise;
  }
  function close(val) {
    this.backdropEl.remove();
    this.backdropElScope.$destroy();
    this.modalWindowEl.remove();
    this.modalWindowElScope.$destroy();
    this.promise.resolve(val);
  }
  return {
    open: open,
    close: close
  }
})
.directive('myModalBackdrop',function($modal){
  return {
  }
})
.directive('myModalWindow',function($modal){
  return {
    template:'<div class="modal" ng-transclude></div>',
    transclude: true,
    link:function(scope, element, attrs){
      element.on('click', function(evt) {
        if(evt.target === evt.currentTarget) {
          $modal.close()
        }
     })
    }
  }
})
<div>hi i'm some component!</div>
angular.module('plunker').component('modalComponent', {
  templateUrl: 'myModalContent.html',
  bindings: {
    close: '&',
    resolve: '<'
  },
  controller: function () {
    var $ctrl = this;

    $ctrl.$onInit = function () {
    
    }

    $ctrl.ok = function () {
      $ctrl.close({val:'shlomo'});
    };

    $ctrl.cancel = function () {
     // $ctrl.dismiss({$value: 'cancel'});
    };
  }
})
  
  <div class="modal-header">
      <h3 class="modal-title" id="modal-title">I'm a modal!</h3>
  </div>
  <div class="modal-body" id="modal-body">
    from resolve:{{$ctrl.resolve.name()}}
  </div>
  <div class="modal-footer">
      <button class="btn btn-primary" type="button" ng-click="$ctrl.ok()">Close</button>
  </div>