ng-model and ng-repeat relation and understanding $scope

前端 未结 2 1255
小鲜肉
小鲜肉 2021-01-16 12:33



        
相关标签:
2条回答
  • 2021-01-16 13:03

    For scenario 2: If you need different scope variable then you need to do like below:

    <li ng-repeat="x in d">
        <input type="text" ng-model="val[$index]" ng-init="val[$index] = x">
    </li>
    

    For Scenario 1&3: The ng-repeated input field are not initialized at first until you the value.

    0 讨论(0)
  • 2021-01-16 13:21

    This is because ng-repeat makes child scope which means it prototypically inherits from container scope. If this is something new to you, google it.. there are lot of explanations for this. Or read this: https://github.com/angular/angular.js/wiki/Understanding-Scopes

    Also, install Angular Batarang in chrome to have a look at scope. This gives you deep insights of what's happening.

    Now, how to deal with this in a clean manner- use controllerAs as following:

    <!DOCTYPE html>
            <html>
              <head>
                <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
              </head>
              <body>
                <div ng-app="myApp" ng-controller="customersCtrl as vm">
                  <ul>
                   <!--Inside ng-repeat-->
                    <li ng-repeat="x in vm.d">
                       {{$index}} <input  ng-model="vm.val">{{vm.val}}
                    </li>
                   <!--Inside ng-repeat--> 
                    <br><br><br>
                   <!--Outside ng-repeat-->
                    Outer<input  ng-model="vm.val">{{vm.val}}
                   <!--Outside ng-repeat-->
                  </ul>
                </div>
                <script>
                  var app = angular.module('myApp', []);
                  app.controller('customersCtrl', function($scope) {
    
                      this.d=[1,2,3,4,5];
    
                  });
                </script>
              </body>
            </html>
    

    Detailed Explaination

    Think of scopes as follows (very coarse implementation though):

    function ParentScope(){
        this.val = "parent";
    }
    
    function ChildScope(){
    
    }
    
    ChildScope.prototype = new ParentScope();
    ChildScope.prototype.constructor = ChildScope;
    
    
    var childScope = new ChildScope();
    

    Explanation of your scenarios:

    1: Whenever you start typing in ng-repeated textbox, ng-model tries to write over "val" property of the childScope, which is not available directly over the child object but at the proto of the object.

    childScope.val = "child"
    

    This statement makes a new property over child object and hides the parent property.

    3: Whenever you type anything in the textbox outside ng-repeat, it changes the "val" in Parent Scope and as the child scopes have been prototypically inherited from parent scope, they can read that property, and hence ng-model tries to read that property and binds to text-box, which is why all ng-repeated text boxes show that value. But, as soon as you type in ng-repeated text-box, it again tries to write over child scope, but ends up making a new property, hiding the parent property.

    I hope that explains that well.

    0 讨论(0)
提交回复
热议问题