ng-model和ng-repeat关系并理解$ scope

时间:2017-02-16 10:01:20

标签: javascript angularjs

		<!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">
			  <ul>
			   <!--Inside ng-repeat-->
				<li ng-repeat="x in d">
				   {{$index}} <input  ng-model="val">{{val}}
				</li>
			   <!--Inside ng-repeat--> 
				<br><br><br>
			   <!--Outside ng-repeat-->
				Outer<input  ng-model="val">{{val}}
			   <!--Outside ng-repeat-->
			  </ul>
			</div>
			<script>
			  var app = angular.module('myApp', []);
			  app.controller('customersCtrl', function($scope) {

				  $scope.d=[1,2,3,4,5];

			  });
			</script>
		  </body>
		</html>
在这里我有5 ng重复的输入字段,其中ng-model为val 当我浏览这段代码

时,我遇到了很多场景

方案1:ng-model = val对于所有重复输入框都是相同的,但当我改变任何重复输入框时,为什么它没有反映在所有表达式中

场景2:如果在重复输入中范围不同,我们如何引用该范围。就像val [o],val [1],val [2]那样

场景3:如果我在外部输入字段中进行更改而不更改或弄脏ng重复的输入字段,则它会反映所有表达式。 但如果我改变任何输入字段,取0,并改变外部输入字段中的值除0外的所有输入字段(1,2,3,4)都在改变... 这里有什么与范围有关,为什么范围表现得像这样?

2 个答案:

答案 0 :(得分:2)

这是因为ng-repeat生成子范围,这意味着它原型继承自容器范围。如果这对您来说是新鲜的东西,那就去吧..对此有很多解释。 或者阅读:https://github.com/angular/angular.js/wiki/Understanding-Scopes

另外,在chrome中安装Angular Batarang以查看范围。这可以让您深入了解正在发生的事情。

现在,如何以干净的方式解决这个问题 - 使用controllerAs 如下:

<!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>

详细说明

将范围想象如下(尽管实现非常粗略):

function ParentScope(){
    this.val = "parent";
}

function ChildScope(){

}

ChildScope.prototype = new ParentScope();
ChildScope.prototype.constructor = ChildScope;


var childScope = new ChildScope();

您的方案说明:

1:每当你开始输入ng-repeated文本框时,ng-model会尝试写入childScope的“val”属性,该属性不能直接在子对象上,而是在 proto 对象。

childScope.val = "child"

此语句在子对象上创建一个新属性,并隐藏父属性。

3:无论何时在ng-repeat之外的文本框中键入任何内容,它都会更改父作用域中的“val”,并且由于子作用域已从父作用域原型继承,因此它们可以读取该属性,从而读取ng-model尝试读取该属性并绑定到文本框,这就是所有重复的文本框显示该值的原因。 但是,只要输入ng-repeated文本框,它就会再次尝试写入子范围,但最终会创建一个新属性,隐藏父属性。

我希望能够解释清楚。

答案 1 :(得分:0)

对于方案2: 如果您需要不同的范围变量,那么您需要执行以下操作:

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

对于场景1和3: 在您输入值之前,首先不会初始化ng重复的输入字段。