20

plunk: http://plnkr.co/edit/85Wl5W If I use the $modalInstance on the same controller(modalController.js), without being in a modal, angular gets frozen.

I just want to simplify my life using angularjs with the angular-ui bootstrap modal service. I want to use the same controller on a separate file, but on a modal as well. That is, I want them to do the same task. Is there any proper way to do it?

E.g. modal.html, modalController.js. I want to show these on a modal window, but on my application as well without a modal. The issue is that if I use the same controller I can't inject the $modalInstance, as it's undefined if there's no modal.

Thanks in advance,

Alex

4
  • You can achieve that by having return value of modal.open in a Var and using that variable fir closing the modal Commented May 21, 2014 at 2:52
  • Some code examples (a Plunkr) would be helpful Commented May 21, 2014 at 14:03
  • I just added a plunk, I hope you understand now what I mean. Commented May 21, 2014 at 16:00
  • duplicate to stackoverflow.com/q/23780950/605586 see my answer: stackoverflow.com/a/34531464/605586 Commented Dec 30, 2015 at 14:32

3 Answers 3

30

It was possible in older version of UI-Bootstrap 0.10.0 .Even latest version,it works for me

index.html

<!-- if you are using Bower -->    
<script src="bower_components/angular-bootstrap/ui-bootstrap.min.js">
</script>
<script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js">
</script>

<!-- modal -->
<!-- look at 'type' and 'id' values -->
<script type="text/ng-template" id="myTestModal.tmpl.html">
    <div class="modal-header">
        <h3>Modal Header</h3>
    </div>   

    <div class="modal-body">
        <p>Modal Body</p>
    </div>

    <div class="modal-footer">
        <button type="button" class="btn btn-default" ng-click="close()" data-dismiss="modal">Close
        </button>
        <button type="button" class="btn btn-primary" ng-click="doSomething()">Do Something
        </button>
    </div> 
</script>

modalDemoController.js

$scope.openModal=function(){
    $scope.modalInstance=$modal.open({
        templateUrl: 'myTestModal.tmpl.html',
        scope:$scope
    });
}

$scope.close=function(){
    $scope.modalInstance.dismiss();//$scope.modalInstance.close() also works I think
};

$scope.doSomething=function(){
    //any actions to take place
    console.log("Do Something");
}
Sign up to request clarification or add additional context in comments.

7 Comments

This seems like a good solution as well! If if($scope.modalInstance) works then it could be used to avoid creating 2 controllers.
A side note: if modalInstance is not something to reference from a view (HTML) then I would not store that into $scope. I think it would be better to keep that as a controller (private) field.
Not sure if you can do this with version before 0.12.0, but you can use $close(result) and $dismiss(reason) directly in the modal markup for the ng-click targets, instead of passing the targets on the modalInstance. Then you can act on the promise returned from "modalInstance.result", as you would with a typical modal.
how to pass data from the main controller to the modal with this approach
@SpencerKormos using $close() was just the solution I needed, thanks.
|
6

I haven't found a clean solution yet, the best workaround I found, to avoid writing the same code twice was to extend the modal controller like this:

$.extend(this, $controller('NormalCtrl', {$scope: $scope}));

full controller:

.controller('ModalCtrl', ['$scope', '$controller', '$modalInstance', 
function ($scope, $controller, $modalInstance) {
    //with this line here:
    // Initialize the super class and extend it.
    $.extend(this, $controller('NormalCtrl', {$scope: $scope}));

    // Opens a search result
    $scope.openResult = function() {
        $modalInstance.close($scope.selectedRow);
    };

    // Called when the cancel button is pressed
    $scope.back = function() {
        $modalInstance.dismiss('cancel');
    };

}]);

That way, I can re-use the same code, without having to rewrite it all over again and I can override the functions that I want to do smth different to the original controller.

Hope I helped some people out there,

Alex

Comments

4

Just write a function instead of creating new file:

 $scope.yourModal= function (data) {
   var modalInstance = $modal.open({
     template: '<div>Do you really want to hurt me? <div><button class="btn" ng-click="hurt(data)">Yes</button></div></div>',
     controller: function($scope, scope){
        $scope = scope;
     },
     resolve: {
         scope: function () {
            return $scope;
         }
     },
     size: 'sm'
   });  
 }

 $scope.hurt = function(data){
     console.log(data);
 }

1 Comment

Would love to hear why this got downvoted. What's wrong with this?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.