Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ui-router: open modal and pass parent scope parameters to it

I am using this FAQ entry to open a modal dialog in a child state of a certain state: https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-open-a-dialogmodal-at-a-certain-state

My code is below. When I open a modal dialog, I need to get access to the properties of the parent state's scope. Is this possible?

plnkr: http://plnkr.co/edit/knY87n

         .state('edit', {
             url: '/{id:[0-9a-f]+}',
             views: {
                 '@': {
                     templateUrl: 'views/edit.html',
                     controller: 'editContr'
                 }
             }
         })
         .state('edit.item', {
             url: "/item/new",
             onEnter: function($stateParams, $state, $modal) {
                 $modal.open({
                     controller: 'itemEditContr',
                     templateUrl: 'views/edit-item.html',
                 }).result.then(function (item) {
                     //
                     // here I need to insert item into the items
                     // seen by my parent state. how?
                     //
                     $state.go('^');
                 }, function () {
                     $state.go('^');
                 });
             }
         });


function editContr($scope) {
    $scope.items = [{name: 'a'}, {name: 'b'}, {name: 'c'}];
}

function itemEditContr($scope, $modalInstance) {
     $scope.submit = function () {
         $modalInstance.close($scope.item);
     };
     $scope.cancel = function () {
         $modalInstance.dismiss('cancel');
     };
     $scope.item = {name: 'test'};
}
like image 526
akonsu Avatar asked Mar 21 '14 03:03

akonsu


2 Answers

Are you planning to update params set by the parent? You should be able to get the parent state using

$state.$current.parent

For e.g. the name of the parent state will be $state.$current.parent.name

EDIT: Updating since the OP wanted to access the Scope and not the parent state.

You can emit an event from the child and then capture it in the parent.

Untested code: In Parent:

$scope.$on('ADD_ITEM', function(evt, msg) {
     $scope.items.add(msg);
}

In the child state:

$scope.$emit('ADD_ITEM', item);
like image 105
rajasaur Avatar answered Oct 11 '22 13:10

rajasaur


long story short, yes it is. Reading the angularjs developer guide for scopes, is actually one of their more helpful and very well documented pieces: http://docs.angularjs.org/guide/scope

Aside from that, scope in angular is no different than scope with any javascript object.

You've got one or two things that you're not doing correctly. For one, passing item in your onEnter function won't help unless you're grabbing something from the url as an identifier, or resloving some data that you can inject into the states controller. You're trying to do the latter, but you aren't resolving anything, so you are getting undefined on item.

One trick you can use is to set a truthy value in your your parent, and access it.

 //in parent ctrl
 $scope.newItem = function(itemname){
     return {name:itemname}
 }

 $scope.save = function(item){
    $scope.items.push(item);
}

Then when you open your modal call $scope.getItem() within the controller instead of injecting item into the controller directly

function itemEditContr($scope, $modalInstance) {
     $scope.submit = function () {
         $modalInstance.close();
     };
     $scope.cancel = function () {
         $modalInstance.dismiss('cancel');
     };
     $scope.item = $scope.newItem('test') //this will look for newItem funciton in the local scope, fail to find it, and walk up the heirarchy until it has found newItem() in the parent

    //now a save function, also defined on the parent scope
    $scope.save($scope.item);


}

Accessing the parent scope is nothing special, just make sure to get a value, and not overwrite it. so you can access $scope.items from the child controller by assigning it to a variable, or you can push it new values, but never set it, or you will create a new local items object on the child scope instead.

like image 27
Brian Vanderbusch Avatar answered Oct 11 '22 15:10

Brian Vanderbusch