Unable to access model values for the angular ui m

2019-08-27 03:33发布

问题:

I am very new to the angular world (second day) and trying to work around angular ui. I am trying to build my first modal dialog. The modal dialog is being shown properly but I m not able to use model in that modal dialog. Here is my demo plunker

Here is what I've done so far:

In controller:

appRoot.controller('DemoCtrl', function ($scope, $modal) {
$scope.openDemoModal= function (size) {
        var modalInstance = $modal.open({
            templateUrl: 'ngPartials/_DemoModal.html',
            controller: 'modalCtrl',
            size: size,
            backdrop: true,
            keyboard: true,
            modalFade: true
        });
    };
});

In index.html:

<div ng-controller="DemoCtrl">
  <a ng-click="openDemoModal()">Open Modal</a>
</div>

In _DemoModal.html

<div class="modal-header">
    <h3 class="modal-title">Test Modal</h3>
</div>
<div class="modal-body">
            <input ng-model="testModel"/>
</div>
<div class="modal-footer">
    <button ng-click="test()">Test</button>
    <button ng-click="cancel()">Cancel</button>
</div>

In controller modalCtrl

appRoot.controller('modalCtrl', function ($scope, $modalInstance) {

    $scope.test= function () {
        var temp = $scope.testModel;//This shows undefined
    };

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

In modalCtrl $scope.testModel always remains undefined no mater what is in the text box. And if I first set the value of $scope.testModel="some value", it will never change no matter what is in the text box. What exactly wrong I am doing.

Also I want to know, if is it possible to have communication between DemoCtrl and modalCtrl ? For this communication I tried to use concept of events as follows:

In modalCtrl:

 $scope.test= function () {
      //var temp = $scope.testModel;//This shows undefined
      $scope.$emit('someEvent', 'some args');
 };

In DemoCtrl:

$scope.$on('someEvent', function (event, args) {
        alert('event called');
});

But this is also not working. What exactly I am doing wrong. Is I am creating angular modal in a wrong way? Any help will be great for me. Thanks in advance.

回答1:

I think this is a prototypical inheritance issue that occurs with teh angular ui bootstrap modal. I can't say I know the exact cause of this (Other than it being $scope related) but I've encountered this many times before and my workaround is to define the main model object on the scope of the modal controller as soon it is created, basically try this;

appRoot.controller('modalCtrl', function ($scope, $modalInstance) {
    //Declare the model explicitly on the controller rather than implicitly on the view
    $scope.testModel="";
    $scope.test= function () {
        var temp = $scope.testModel;//This shows undefined
    };

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

EDIT:

Examining the $scope of the modal shows that the testModel object exists on the $$childTail scope, meaning the modal has created a new child $scope for itself, and is binding testModel to that $scope. A workaround is to use ng-model="$parent.testModel" to reference the parent $scope (the correct scope, the one we defined for the modal).

Working plunk.



回答2:

It looks like you are having a scope issue. In other words, your model testModel is created inside a different scope, a child scope. So to fix your issue simply use object attached to your modal scope rather than a variable:

appRoot.controller('modalCtrl', function($scope, $modalInstance) {
  $scope.data = {
    testModel: ""
  };
  $scope.test = function() {
    var temp = $scope.data.testModel; //This shows undefined
    alert(temp);
  };

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

Check an updated plunk

UPDATE:

Now you want a way to communicate between two controllers using $emit. To fix your code you need just to specify the parent scope while creating the modal, so you just need to update your code like this:

$scope.openDemoModal = function(size) {
    var modalInstance = $modal.open({
      templateUrl: '_DemoModal.html',
      controller: 'modalCtrl',
      size: size,
      backdrop: true,
      keyboard: true,
      modalFade: true,
      scope: $scope // that's what you need to add.
    });
  };

Working demo for update