$ scope。父控制器上的$ watch不会触发子ng-select

时间:2014-07-03 19:46:27

标签: javascript angularjs

使用案例

使用绑定到控制器变量的select,无论何时,父控制器中存在该变量,并且父节点中的该变量都创建了$watch,父$watch不开火。 为什么会这样?

代码

随机数据生成器实用程序功能

此代码并不重要,但为了清楚起见,包括在内。

function populate(x) {
    var items = [];
    for (var i = 0; i < x; i++) {
        items.push( { label: 'item ' + i,
                     data: { value: 'some value ' + i },
                     id: i });
    }
    return items;
};

家长控制器

function parent($scope) {
  $scope.items = populate(10);
  $scope.selected = $scope.items[0];
  $scope.fired = 0;

  $scope.$watch('selected.id', function(id) {
      $scope.fired++;
  });
};

儿童控制器

function child($scope) {

};

场景1

此方案的工作原理如上所述。在这种情况下,只要用户更改select的值,变量$scope.fired就会递增。 jsFiddle

视图
<div ng-app>
    <div ng-controller="parent">
        <select ng-model="selected"
                ng-options="item as item.label for item in items">
        </select>
        <pre>
            {{ fired | json }}
        </pre>
        <pre>
            {{ selected | json }}
        </pre>
    </div>
</div>

场景2

在以下情况中,$watch将在父级中触发而不是。但是,如果将$watch移动到子控制器,它将会触发。 注意:与上面的代码相比,更改位于第3行。 jsFiddle

视图
<div ng-app>
    <div ng-controller="parent">
        <div ng-controller="child">
            <select ng-model="selected"
                    ng-options="item as item.label for item in items">
            </select>
            <pre>
                {{ fired | json }}
            </pre>
            <pre>
                {{ selected | json }}
            </pre>
        </div>
    </div>
</div>

问题

为什么包含子控制器导致$watch不会触发,即使子控制器继承了$scope

1 个答案:

答案 0 :(得分:2)

家长selected并没有改变自己。儿童范围selected是。这就是为什么手表没有像你期望的那样工作的原因。这是由于原型继承。

$watch本身应该在子范围内定义,无论父范围是否是第一个声明它的范围。