如何$观看由ng-repeat创build的模型的更改?

例如,考虑这个Plnkr 。 我不知道有多lessfooCollection会员会被预先创build。 所以我不知道有多lessbar模型将会存在。

但是我知道他们将成为angular色模型,我知道他们将会在哪里。

我该如何做$watch

我需要这样做,因为我需要在更改bar模型时触发行为。 观察fooCollection本身是不够的, $watch bar监听器不会在更改bar时触发。

相关html:

 <body ng-controller="testCtrl"> <div ng-repeat="(fooKey, foo) in fooCollection"> Tell me your name: <input ng-model="foo.bar"> <br /> Hello, my name is {{ foo.bar }} </div> <button ng-click="fooCollection.push([])">Add a Namer</button> </body> 

相关JS:

 angular .module('testApp', []) .controller('testCtrl', function ($scope) { $scope.fooCollection = []; $scope.$watch('fooCollection', function (oldValue, newValue) { if (newValue != oldValue) console.log(oldValue, newValue); }); }); 

创build单独的列表项控制器: 在Plnkr上演示

JS

 angular .module('testApp', []) .controller('testCtrl', function ($scope) { $scope.fooCollection = []; }) .controller('fooCtrl', function ($scope) { $scope.$watch('foo.bar', function (newValue, oldValue) { console.log('watch fired, new value: ' + newValue); }); }); 

HTML

 <html ng-app="testApp"> <body ng-controller="testCtrl"> <div ng-repeat="(fooKey, foo) in fooCollection" ng-controller="fooCtrl"> Tell me your name: <input ng-model="foo.bar" ng-change="doSomething()"> <br /> Hello, my name is {{ foo.bar }} </div> <button ng-click="fooCollection.push([])">Add a Namer</button> </body> </html> 

如果您的collections已填充,则可以在ng-repeat的每个项目上放置一个手表:

HTML

 <div ng-repeat="item in items"> {{ item.itemField }} </div> 

JS

 for (var i = 0; i < $scope.items.length; i++) { $scope.$watch('items[' + i + ']', function (newValue, oldValue) { console.log(newValue.itemField + ":::" + oldValue.itemField); }, true); } 

您可以将true作为第三个parameter passing给$ watch

 $scope.$watch('something', function() { doSomething(); }, true); 

https://docs.angularjs.org/api/ng/type/$rootScope.Scope

您也可以创build自定义指令,告诉主控制器更改

 YourModule.directive("batchWatch",[function(){ return { scope:"=", replace:false, link:function($scope,$element,$attrs,Controller){ $scope.$watch('h',function(newVal,oldVal){ if(newVal !== oldVal){ Controller.updateChange(newVal,oldVal,$scope.$parent.$index); } },true); }, controller:"yourController" }; }]); 

假设你的标记是这样的

 <ul> <li ng-repeat="h in complicatedArrayOfObjects"> <input type="text" ng-model="someModel" batch-watch="$index" /> </li> </ul> 

这是你的控制器

 YourModule.controller("yourController",[$scope,function($scope){ this.updateChange = function(newVal,oldVal,indexChanged){ console.log("Details about the change"); } }]); 

你也可以使用前面3个参数,scope,element和attr指令链接函数提供的值。

因为我不想要另一个控制器,所以我最终使用了ng-change 。

简单的jsFiddle: https ://jsfiddle.net/maistho/z0xazw5n/

相关HTML:

 <body ng-app="testApp" ng-controller="testCtrl"> <div ng-repeat="foo in fooCollection">Tell me your name: <input ng-model="foo.bar" ng-change="fooChanged(foo)"> <br />Hello, my name is {{foo.bar}}</div> <button ng-click="fooCollection.push({})">Add a Namer</button> </body> 

相关JS:

 angular.module('testApp', []) .controller('testCtrl', function ($scope) { $scope.fooCollection = []; $scope.fooChanged = function (foo) { console.log('foo.bar changed, new value of foo.bar is: ', foo.bar); }; }); 

尝试做到这一点

  <div ng-repeat="foo in fooCollection" ng-click="select(foo)">Tell me your ame: <input ng-model="foo.bar" ng-change="fooChanged(foo)"> <br />Hello, my name is {{foo.bar}}</div> <button ng-click="fooCollection.push({})">Add a Namer</button> </div> 

指令/控制器中有代码

  $scope.selectedfoo = {}; $scope.select = (foo) => { $scope.selectedfoo = foo; } $scope.$watch('selectedfoo ', (newVal, oldVal) => { if (newVal) { } },true)