【问题标题】:ng-model and ng-repeat relation and understanding $scopeng-model 和 ng-repeat 关系和理解 $scope
【发布时间】:2017-02-16 20:15:41
【问题描述】:

		<!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>
在这我有五个 ng-repeated 输入字段与 ng-model 作为 val 当我浏览这段代码时,我遇到了很多场景

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

场景2:如果重复输入的作用域不同,如何引用那个作用域,是不是像val[o],val[1],val[2]这样的

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

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    这是因为 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 重复文本框都显示该值的原因。 但是,一旦您输入 ng-repeated 文本框,它就会再次尝试覆盖子范围,但最终会创建一个新属性,隐藏父属性。

    我希望这能很好地解释这一点。

    【讨论】:

      【解决方案2】:

      对于场景 2: 如果您需要不同的范围变量,则需要执行以下操作:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-22
        • 2019-10-25
        • 2023-04-09
        • 2017-11-19
        • 2017-02-11
        • 1970-01-01
        • 1970-01-01
        • 2015-08-13
        相关资源
        最近更新 更多