单击选中嵌套ng-repeat内的复选框

时间:2017-07-19 15:03:01

标签: angularjs angularjs-scope angularjs-ng-repeat angularjs-ng-model

请详细了解演示掠夺者。

Demo Plunker

Example1

Example1的html看起来像这样

<tr ng-repeat="class in Classes">
            <td>{{class.name}}</td>
            <td>
              <span ng-repeat="subject in Subjects ">
                <input type="checkbox" name="{{subject.name}}" ng-model="subject.model" 
                ng-change="Print(subject)">{{subject.name}}
              </span>
            </td>
          </tr>

在上面的plunker中,当点击任何一个复选框时,为什么都被选中?

Demo Plunker

Example2

Example2的HTML喜欢

<tr ng-repeat="class in Classes">
        <td>{{class.name}}</td>
        <td>
          <span ng-repeat="subject in Subjects ">
            <input type="checkbox" ng-model="Subject" 
            ng-change="Print(subject,class)">{{subject.name}}
          </span>
        </td>
      </tr>

在上面的plunker中,当点击任何一个复选框时,只选择了一个?

Example1和Example2之间的区别是 ng-model 。在Example1中,$ scope中的默认值分配给ng-model,但在Example2中分配的新变量不是$ scope。我知道如果范围内已经存在ng-model属性,它将被隐式创建并添加到范围中。

为什么在Example2中可以选择单个复选框,为什么不在Example1中?

1 个答案:

答案 0 :(得分:1)

原因是 JavaScript Prototypal Inheritance

范围继承通常很简单,你甚至不需要知道它正在发生......直到你尝试双向数据绑定(即表单元素,ng-model)到一个原语(例如,数字,字符串,布尔值)在子范围内从父范围内定义。它不像大多数人期望的那样工作。会发生的事情是子范围获得自己的属性隐藏/阴影同名的父属性。这不是AngularJS正在做的事情 - 这就是JavaScript原型继承的工作原理。

由于您正在为第二种情况使用原语,因此您的所有ng-model子范围都将创建自己的属性,隐藏/隐藏同名的父属性。

第一个场景中,在使用对象的情况下,由于每个ng-model子作用域都直接绑定到父作用域,因此不会看到上述行为。 ng-repeat的子实例)。

假设有一个第三种情况,您在控制器中创建了第二个ng-model="Subject.modal"并声明了$scope.Subject={},现在选中一个复选框将全部检查,因为该值是直接的无论ng-repeat的子范围如何,都绑定到父母的范围。

有关详情:https://github.com/angular/angular.js/wiki/Understanding-Scopes