0

I wanted to define a custom scope for the modal (I don't want to use dependency injection for reasons) I am using in my project, but I'm getting an error whenever I define a scope in $modal.open. Here is the plunk I created from the example on AngularUI's website: http://plnkr.co/edit/rbtbpyqG7L39q1qYdHns

I tried debugging and saw that (modalOptions.scope || $rootScope) returns true with a custom scope and since true (obviously) doesn't have a $new() function defined, an exception is thrown.

Any thoughts?

oakgun
  • 170
  • 1
  • 9
  • Do you want to use $scope.test inside ModalInstanceCtrl? – Jorge Casariego Jun 04 '15 at 11:49
  • Yes, I have some scope variables and methods I want to pass to the modal but like I said I don't want to use dependency injection for it. – oakgun Jun 04 '15 at 11:54
  • One more note: (modalOptions.scope || $rootScope) may _evaluate_ to true, but it _returns_ the first truthy value it finds (modalOptions.scope or $rootScope), not the literal true itself – Robin-Hoodie Jun 04 '15 at 12:27
  • I just checked again: you're right about that. But it _actually_ returns true when you set the `scope: true`, which was one of the things I tried based on [this answer for creating child scopes.](http://stackoverflow.com/a/14914798/1086915) – oakgun Jun 04 '15 at 12:37

2 Answers2

2

You'll have to pass a scope instance:

var modalInstance = $modal.open({
      animation: $scope.animationsEnabled,
      templateUrl: 'myModalContent.html',
      controller: 'ModalInstanceCtrl',
      size: size,
      resolve: {
        items: function () {
          return $scope.items;
        }
      },
      scope: $scope
    });

You can also pass your own custom scope if you don't want to use the controller's scope, working plnkr:

http://plnkr.co/edit/1GJTuVn45FgPC3jIgyHv?p=preview

Robin-Hoodie
  • 4,886
  • 4
  • 30
  • 63
  • I think I like this approach but if I create a scope myself using `$new()`, I'll have to destroy it manually right? I still don't get why `scope: { test: $scope.test; }` doesn't work though, is it because `$modal` is a provider? – oakgun Jun 04 '15 at 12:16
  • You're giving an object to the scope instead of a scope instance, not every object is a scope instance, don't confuse the scope property on the $modal service with the scope property when you create a custom directive. – Robin-Hoodie Jun 04 '15 at 12:19
0

First Way

To pass a variable to a modal you can do it in this way

var modalInstance = $modal.open({
      animation: $scope.animationsEnabled,
      templateUrl: 'myModalContent.html',
      controller: 'ModalInstanceCtrl',
      size: size,
      resolve: {
        items: function () {
          return $scope.items;
        },
        test: function(){
          return  $scope.test;   //This is the way
        }
      }
    });

In your modal you have this

angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $modalInstance, items, test) {

  $scope.items = items;
  $scope.test = test;   // And here you have your variable in your modal

  console.log("Test: " + $scope.test)

  $scope.selected = {
    item: $scope.items[0]
  };

  $scope.ok = function () {
    $modalInstance.close($scope.selected.item);
  };

  $scope.cancel = function () {
    $modalInstance.dismiss('cancel');
  };
});

Here you have your own example in Plunker

Second Way

var modalInstance = $modal.open({
      animation: $scope.animationsEnabled,
      templateUrl: 'myModalContent.html',
      controller: 'ModalInstanceCtrl',
      size: size,
      scope: $scope,    // In this way
      resolve: {
        items: function () {
          return $scope.items;
        }
      }
    });

angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $modalInstance, items) {

  $scope.items = items;

  //You have available test and hello in modal
  console.log("Test 1: " + $scope.test);  
  console.log("Test 2: " + $scope.hello);

  $scope.selected = {
    item: $scope.items[0]
  };

  $scope.ok = function () {
    $modalInstance.close($scope.selected.item);
  };

  $scope.cancel = function () {
    $modalInstance.dismiss('cancel');
  };
});

Plunker of the second way

Jorge Casariego
  • 21,948
  • 6
  • 90
  • 97