$ watch或$ watchCollection不适用于ng-repeat

时间:2016-07-13 15:29:59

标签: javascript angularjs

我在主app控制器中定义了一个item对象,该对象有3个布尔项。我将此对象发送到具有隔离范围的指令。在这个指令中,我使用ng-repeat迭代接收到的对象,并在items对象中创建带有ng-model = item的复选框。

但我无法观察物品对象的变化(由指令上的ng-model完成)。我放的$ watchCollection似乎不起作用。

JavaScript的:

var myApp = angular.module('myApp', []);

myApp.controller('MyCtrl', function($scope) {
  $scope.items = {
    item1: true,
    item2: false,
    item3: true
  };

  $scope.$watchCollection('items', function(newVal, oldVal) {
    console.log(oldVal, newVal);
  });

});

myApp.directive('testDirective', function() {
  return {
    restrict: 'E',
    replace: true,
    scope: {
      items: '='
    },
    template: "<div ng-repeat='(item,val) in items'><label><input type='checkbox' ng-model='val'/>{{item}}</label></div>"
  }
});

HTML:

<div ng-controller="MyCtrl">
  <test-directive items="items"></test-directive>
</div>

但是,如果在指令HTML中,我不使用ng-repeat并手动创建单独的复选框,那么$ watchCollection会正确地监视更改:

<div>
  <label>
    <input type='checkbox' ng-model='items.item1' />Item1</label>
  <label>
    <input type='checkbox' ng-model='items.item2' />Item2</label>
  <label>
    <input type='checkbox' ng-model='items.item3' />Item3</label>
</div>

以下是问题的JSFiddle链接: https://jsfiddle.net/rishabh1990/0kb6tezd/

1 个答案:

答案 0 :(得分:1)

$ watchCollection 仅在您的收藏集数据发生变化(添加,删除)时才有效,而不是内部数据发生变化时。

为了观察内部数据的变化,你可以写一下

  $scope.$watch('items', function(newVal, oldVal) {
    console.log(oldVal, newVal);
  }, true);

已编辑请参阅此处

https://jsfiddle.net/5bf3v0xj/

为什么

 $scope.items = [
    {name: 'item1', value: true},
    {name: 'item2', value: false},
    {name: 'item3', value: true}
  ];

而不是

 $scope.items = {
        item1: true},
        item2: false},
        item3: true}
      }

<强>说明

因为ng-repeat创建了自己的scope并复制了基元值。

字符串表现为原始值,因此ng-repeat将拥有它自己的副本这些变量。并且因为您观看 原件`而不是永远不会开火。

还有一件事:在 ng-repeat变量中加.是一种好方式:
 喜欢 代码中的ng-model='item.value