Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular UI Modal 2 Way Binding Not Working

I am adding an Angular UI Modal where I am passing the scope through to the Modal Window for 2 way binding. I used the resolve method to pass the scope value. Doing so works sort of works meaning when the ng-model value changes in parent, it reflects inside the modal window. However, if the value changes inside the modal window, it is not reflecting in the parent ng-model. Here is my code:

HTML:

<div ng-app="app">
    <div ng-controller="ParentController">
        <br />
        <input type="text" ng-model="textbox.sample" /> 
        <a class="btn btn-default" ng-click="open(textbox.sample)">Click Me</a> 

        <script type="text/ng-template" id="ModalContent.html">
            <input type = "text" ng-model= "ngModel" / >
        </script>


        <br />{{ textbox }}        
    </div>
</div>

Controller:

var app = angular.module('app', ['ui.bootstrap']);

app.controller('ParentController', function ($scope, $modal) {

    $scope.textbox = {};

    // MODAL WINDOW
    $scope.open = function (_ngModel) { // The ngModel is passed from open() function in template   
        var modalInstance = $modal.open({
            templateUrl: 'ModalContent.html',
            controller: ModalInstanceCtrl, 
            resolve: {
                ngModel: function () {
                    return _ngModel;
                }
            } // end resolve
        });
    };
});

var ModalInstanceCtrl = function ($scope, $modalInstance, ngModel) {
    $scope.ngModel = ngModel;

};

Why isint the 2 way binding between parent and modal instance not working in the above code?

like image 964
Neel Avatar asked May 07 '14 13:05

Neel


3 Answers

Change:

<input type = "text" ng-model= "ngModel" / >

Into:

<input type = "text" ng-model= "$parent.ngModel" / >

This has to do with transclusion. Check: https://github.com/angular-ui/bootstrap/issues/969

like image 158
Diana Nassar Avatar answered Nov 12 '22 03:11

Diana Nassar


I think you're under the impression that ng-model="textbox.sample" in the parent and ng-model="ngModel" in the modal are the same because you are passing textbox.sample to the modal and you're able to see the correct value in the modal window. The only reason this is working is because you're explicitly setting the $scope.ngModel property every time to modal window opens.

One way to make this work how you expect is to just use the $scope.textbox.sample property in both places, but I wouldn't recommend that.

Perhaps the proper way would be to use the modalInstance.result promise, something like this:

Create a button on the modal and make it's ng-click="ok()"

$scope.ok = function () {
    $modalInstance.close($scope.ngModal); // will return this to the modalInstance.result
}

And then in the parent controller, or whatever opens the modal window:

$scope.open = function (_ngModel) { // The ngModel is passed from open() function in template   
    var modalInstance = $modal.open({
        templateUrl: 'ModalContent.html',
        controller: ModalInstanceCtrl, 
        resolve: {
            ngModel: function () {
                return _ngModel;
            }
        } // end resolve
    });

    modalInstance.result.then(function (result) {
        $scope.textbox.sample = result;
    });
};
like image 31
Tom Avatar answered Nov 12 '22 03:11

Tom


For me none of the above worked.

Instead I had to do like was suggested in this comment in github.

The variable to be binded to must be an object, not only a simple value.

For example, if $scope.value does not work, it will work if you use $scope.someObject.value.

like image 2
Ulysses Alves Avatar answered Nov 12 '22 02:11

Ulysses Alves