1
votes

I'm launching a modal from my web page and i'm making some changes to an array that i'm passing from my parent, but before I send the updated results back after closing the modal my parent scope object is getting updated. If the user changed the mind not to update and then cancel the modal I don't want those changes to be seen on my parent controller

  • Parent Controller Code:

    const modalInstance = $modal.open({ templateUrl: '/app/modal.html', controller: 'modalController', controllerAs: 'modal', resolve: {
    mappedData: () => parentCntrl.groupData } });

            modalInstance.result.then(result => {
                if (result) {                   
                    parentCntrl.groupData = result;
                }
            });
    
  • Child Controller Code:

    modal.ok = () => { $modalInstance.close(modal.mappedData); };

    modal.close = () => { $modalInstance.close(); };

3

3 Answers

2
votes

Because the data you are passing down is a non primitive type, so not an number or string for example, this will be copied by reference in memory.

You should make a copy of the data and use the copied version in the modal and when the modal is saved use that copied version to merge any changes back to the original object in the parent controller

A very similar question asked here Using AngularJS "copy()" to avoid reference issues and how angular.copy() can be used to avoid reference issues

0
votes

When you instantiate a $uibModal, you define a configuration object, where the setting scope : should be the object reference that this modal will use (as a scope). It is pretty normal to define something like scope: $scope. This way, if the variables inside the modal controller have the same names as the ones in the parent scope, then the assignment would occur to the same object. As some comments say, the use of angular.copy() would be a good idea or maybe a simple $rootScope.new();

var modalInstance = $uibModal.open({
  ...
  scope : $rootScope.new(),
  //or
  scope : angular.copy($scope)
  ...
});

I hope this helps

0
votes

You can also try this simple code.

HTML:

<tr ng-repeat="users in list">
  <td>{{users.firstname}}</td>
  <td>{{users.lastname}}</td>
  <button class="btn btn-primary" data-toggle="modal" data-target="#myModal" ng- 
  click="selectUser(users)">Edit Info</button>
</tr>

Controller:

$scope.selectUser = function(users){ $scope.clickedUser = users; $scope.modalInfo = angular.copy($scope.clickedUser); };

Modal:

<div class="modal fade" id="myModal" role="dialog">
  <div class="modal-dialog">
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal">&times;</button>
            <h2 class="modal-title">Update bio</h2>
        </div>
        <div class="modal-body">
            <input type="text" ng-model="modalInfo.firstname">
            <input type="text" ng-model="modalInfo.lastname">
        </div>
        <div class="modal-footer">
            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        </div>
    </div>
</div>