6

In my angularjs app I use UI Bootstrap for creating modals. I pass scope and custom controller into the modal, it shows my data from original scope but cannot perform any of its function. I have main controller:

myapp.controller('WsCtrl', function WsCtrl($scope, $location, todoStorage, filterFilter, $modal, $log) {

In controller I have next:

$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function () {
    var modalInstance = $modal.open({
        templateUrl: 'partials/users.html',
        scope: $scope,
        controller: ModalInstanceCtrl,
        resolve: {
            items: function () {
                return $scope.items;
            },
            users: function(){
                return $scope.users;
            },
            CurrentDate: function(){
                return $scope.CurrentDate;
            }
        }
    });

    modalInstance.result.then(function (selectedItem) {
        console.log(selectedItem);
    }, function () {
        $log.info('Modal dismissed at: ' + new Date());
    });
};

And also I have another function outside the controller:

var ModalInstanceCtrl = function ($scope, $modalInstance, items) {

    $scope.items = items;
    $scope.users = users;
    $scope.CurrentDate = CurrentDate;
    $scope.selected = {
        item: $scope.items[0]
    };
    $scope.num = 11;

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

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

When I pass the scope to modal - I can see all my users, but I can't add one 'cause off problem with functions in my original scope.

2
  • Could you post the code for those functions? I'm seeing no problems with your code. Here's a plunker to prove that adding items works: plnkr.co/edit/j79MkkyEcgS4l8MxbbxV?p=preview Commented Oct 1, 2013 at 16:14
  • Of course, I've seen this plunker as an example. Commented Oct 1, 2013 at 17:04

2 Answers 2

22

You don't need scope: $scope. The resolve parameter is responsible for passing variables to ModalInstanceCtrl. But you must add those parameters to its dependencies (their names must match those from resolve), so if you had:

resolve: {
    foo: function(){
        return $scope.something
    }
}

then you must have

var ModalInstanceCtrl = function ($scope, $modalInstance, foo) {
    $scope.foo = foo;
    // ...
}

Oh, and functions can be passed just like other variables, inside resolve:

resolve: {
    someFunction: function(){
        return $scope.someFunctionFromOriginalScope
    }
}

Additionally, you can inject any other service in the resolve section and perform additional logic inside of it:

resolve: {
    someFunction: function(configService){
        if (configService.isProduction){
            return angular.noop;
        } else {
            return $scope.someFunctionFromOriginalScope;
        }
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

I've tried this. But anyway I've dealt with problems of scope variables and functions. I've decided to go by not so true way for angular and mvc and I used jquery modal windows for that. Other fucntions of ui.bootstrap work just fine (e.g. alerts, pagination, etc). Will investigate ui.bootstrap modals in future.
We still don't understand your problem.
Nice answer! This helped me alot too! =)
Why do we need to pass functions wrapped in another function?
@naXa - you cannot pass function without wrapping because the outer function is executed during instantiation of modal controller. Please look at the end of my answer, I've addded small additional section that explains why it's done this way.
10

If you really need to pass a custom scope (i.e., if you want to avoid a dependency injection not always satisfied), you would do it this way:

$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function () {
    var modalInstance = $modal.open({
        templateUrl: 'partials/users.html',
        scope: function() {
            var scope = $rootScope.$new();
            scope.items = $scope.items;
            scope.users = $scope.users;
            scope.currentDate = $scope.currentDate;
            scope.someFunction = function () {
                // do some stuff with scope.items
            }
            return scope;
        }(),
        controller: 'ModalInstanceCtrl'
    });

    modalInstance.result.then(function (selectedItem) {
        console.log(selectedItem);
    }, function () {
        $log.info('Modal dismissed at: ' + new Date());
    });
};

And your controller would look like this:

var ModalInstanceCtrl = function ($scope, $modalInstance) {
    // Your controller already has $scope.items, $scope.users, $scope.currentDate and $scope.someFunction

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

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

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

Comments

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.