Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angularjs updating data in parent scope after modal form submission

Tags:

angularjs

I am unable to figure out how to update the $scope.dir in the parent scope (DirCrl) from the child scope (ModalCtrl). The view is a simple modal form with a single text input. On submit the text input is bound to mkdir.name in the child scope. The child controller makes a REST call to a database and should update $scope.dir in the parent scope with the response data. Any guidance will be greatly appreciated. Code snippet below

app.controller('DirCtrl', ['$scope', '$http', function ($scope, $http) {

$scope.dir = {};
$scope.mySelections = [];

$http({
    method: 'GET',
    url: '//localhost:9090/fx/v1/dir/52cdc7304c3525ac0c5cdd3a'
})
    .success(function (data, status, headers, config) {
        $scope.dir = data;
        $scope.children = data.children;
    })
    .error(function (data, status, headers, config) {
    });

}]);

var ModalCtrl = function ($scope, $modal, $log) {

$scope.mkdir = {
    name: 'name',
    data: {}
};

$scope.$parent.ben = 'ben01';

$scope.open = function () {

    var modalInstance = $modal.open({
        templateUrl: 'myModalContent.html',
        backdrop: true,
        windowClass: 'modal',
        controller: ModalInstanceCtrl,
        resolve: {
            mkdir: function () {
                return $scope.mkdir;
            }
        }
    });

    modalInstance.result.then(function () {
        $scope.$parent.children = $scope.mkdir.data.children;
    });
};
};

var ModalInstanceCtrl = function ($scope, $modalInstance, $http, $log, mkdir) {
$scope.mkdir = mkdir;
$scope.submit = function () {
    $log.log('name of directory to create');
    $log.log(mkdir.name);

    $http({
        method: 'GET',
        url: '//localhost:9090/fx/v1/dir/52cdcce74c358cdfe2fa2c83'
    })
        .success(function (data, status, headers, config) {

          $scope.mkdir.data = data;
        })
        .error(function (data, status, headers, config) {

        });
    $modalInstance.dismiss('cancel');
}


$scope.cancel = function () {
    $modalInstance.dismiss('cancel');
};
};
like image 325
user3146617 Avatar asked Jan 25 '14 22:01

user3146617


3 Answers

CORRECTION:

In the child do something like:

$scope.$emit('whatevereventnameyouwant', data);

In the parent listen for that event:

$rootScope.$on('whatevereventnameyouwant', function(event, data) { console.log(data); });
like image 138
Khalil Avatar answered Oct 02 '22 14:10

Khalil


Using promise (standard way)

The standard way to return data back to the invoking controller once the modal is closed is to register a callback once the promise is resolved:

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

Using events

You can also dispatch an event upwards through the scope hierarchy by invoking $emit:

$scope.$emit(name, args);

The parent scope can then listen for the event by invoking $on:

$scope.$on('eventName', function(event, data) { console.log(data); });

When creating a new modal, it's $scope will be a child of the $rootScope by default. When $emit() is invoked, it looks on it's own scope (i.e. the modal's $scope) for any registered listeners, invokes them (if present), then traverses the scope chain upwards until it runs out of parents. If the parent scope isn't specified when creating the modal, calling $scope.$emit('eventName', data) will bypass the controller's scope when evaluating the scope chain. Both the invoking controller and the modal controller can work directly with the $rootScope when calling $emit() and $on(), but you typically want to associate a modal's scope with it's invoking controller's $scope hierarchy. To set the parent scope of the modal, set the scope parameter to $scope as following:

    var modalInstance = $modal.open({
    templateUrl: 'myModalContent.html',
    backdrop: true,
    windowClass: 'modal',
    controller: ModalInstanceCtrl,
    scope: $scope,
    resolve: {
        mkdir: function () {
            return $scope.mkdir;
        }
    }
});
like image 40
Derek Greer Avatar answered Oct 02 '22 15:10

Derek Greer


Sounds like you want to $scope.$emit() back up to the parent.

In the child do something like:

$scope.$emit('whatevereventnameyouwant', data);

In the parent listen for that event:

$scope.$on('whatevereventnameyouwant', function(event, data) { console.log(data); });
like image 42
rg88 Avatar answered Oct 02 '22 13:10

rg88