最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular UI Modal 2 Way Binding Not Working - Stack Overflow

programmeradmin2浏览0评论

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?

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?

Share Improve this question asked May 7, 2014 at 13:12 NeelNeel 9,88023 gold badges93 silver badges130 bronze badges 5
  • 1 Where are you actually expecting to see the two-way binding happen, where you're printing out {{textbox}} ? If that's the case, you're no longer acting on $scope.textbox once you're in the modal, you're creating a copy of $scope.textbox when you pass it as _ngModel and then you modal $scope item is $scope.ngModel... Try printing {{ngModel}} on the parent and see what happens – Tom Commented May 7, 2014 at 13:21
  • Its better to pass $scope as option parameter in modals open function – Armen Commented May 7, 2014 at 13:24
  • @Tom When I said 2 way binding, what I meant by that is I want the text box input in parent and modal window to change if any of those values changes. For instance, in my example, the ng-model for input in parent and the input in modal window is the same. So when I type something in parent input and then open the modal, I can see the modal input having the same value. But when I type something inside the modal instance's input, it is not updating it on parent input. When those 2 are binded by the same ng-model, shouldnt it update? – Neel Commented May 7, 2014 at 13:31
  • 1 @blackops_programmer, they aren't the same ng-model="ngModel" and ng-model="textbox.sample" are different and thus will not update eachother. The reason it works from the parent to the modal is because you're setting that every time you open the modal window. – Tom Commented May 7, 2014 at 13:33
  • aha.. so if I want the parent ng-model to reflect any change done inside the modal instance, how do I do that? Would placing a $watch in parent controller work in this case? If so, how can I add that? – Neel Commented May 7, 2014 at 13:36
Add a comment  | 

3 Answers 3

Reset to default 10

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

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;
    });
};

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.

发布评论

评论列表(0)

  1. 暂无评论