11
votes

I want to use the modal to edit my data. I pass the data to the modal instance. When I click ok I pass the edited data in the $scope.selected back to the controller.

There I would like to update the original $scope. Somehow the $scope doesn't update though. What am I doing wrong?

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

  $scope.data = { name: '', serial: ''  }

  $scope.edit = function (theIndex) {

    var modalInstance = $modal.open({
      templateUrl: 'myModalContent.html',
      controller: ModalInstanceCtrl,
      resolve: {
        items: function () {
          return $scope.data[theIndex];
        }
      }
    });

    modalInstance.result.then(function (selectedItem) {
      $scope.selected = selectedItem;

      // this is where the data gets updated, but doesn't do it
      $scope.data.name = $scope.selected.name;
      $scope.data.serial = $scope.selected.serial;

    });
  };
};

Modal Controller:

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

  $scope.items = items;
  $scope.selected = {
    name: $scope.items.name,
    serial: $scope.items.serial
  };

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

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

Modal:

<div class="modal-header">
    <h3>{{ name }}</h3>
</div>
<div class="modal-body">
    <input type="text" value="{{ serial }}">
    <input type="text" value="{{ name }}">
</div>
<div class="modal-footer">
    <button class="btn btn-primary" ng-click="ok()">OK</button>
    <button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
1
Hehe thx ye little typo, but doesn't solve the problem :-)Tino

1 Answers

14
votes

You didn't include your template for the modal, so this is a bit of a guess. Your code is pretty close to the example code for the angular-ui modal, which uses ng-repeat in the template. If you're doing the same thing, then you should be aware that ng-repeat creates a child scope which inherits from the parent.

Judging from this snippet:

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

it looks like instead of doing this in your template:

<li ng-repeat="item in items">
    <a ng-click="selected.item = item">{{ item }}</a>
</li>

you may be doing something like this:

<li ng-repeat="item in items">
    <a ng-click="selected = item">{{ item }}</a>
</li>

If so, then in your case, you're assigning selected in the child scope, and this will not affect the parent scope's selected property. Then, when you try to access $scope.selected.name, it will be empty. In general, you should use objects for your models, and set properties on them, not assign new values directly.

This part of the documentation explains the scope problem in more detail.

Edit:

You are also not binding your inputs to any model at all, so the data you enter there is never stored anywhere. You need to use ng-model to do that, e.g.:

<input type="text" ng-model="editable.serial" />
<input type="text" ng-model="editable.name" />

See this plunkr for a working example.