Consider this Plnkr for example. I don't know how many members of fooCollection
will be created beforehand. So I don't know how many bar
models are going to exist.
But I know they are going to be angular models, and I know where they are going to be.
How do I do a $watch
on these?
I need to do that because I need to trigger behavior when a bar
model is changed. Watching the fooCollection itself is not enough, the $watch
listener does not fire when a bar
is changed.
Relevant 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>
Relevant JS:
angular .module('testApp', []) .controller('testCtrl', function ($scope) { $scope.fooCollection = []; $scope.$watch('fooCollection', function (oldValue, newValue) { if (newValue != oldValue) console.log(oldValue, newValue); }); });
Directives that Create Scopes In most cases, directives and scopes interact but do not create new instances of scope. However, some directives, such as ng-controller and ng-repeat, create new child scopes and attach the child scope to the corresponding DOM element.
The ng-repeat values can be filtered according to the ng-model in AngularJS by using the value of the input field as an expression in a filter. We can set the ng-model directive on an input field to filter ng-repeat values.
You can consider using transclusion inside a custom directive, to achieve the behavior you are looking for without using ng-repeat.
Definition and Usage. The ng-repeat directive repeats a set of HTML, a given number of times. The set of HTML will be repeated once per item in a collection. The collection must be an array or an object. Note: Each instance of the repetition is given its own scope, which consist of the current item.
Create individual list-item controllers: demo on Plnkr
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 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>
If you have your collection populated, you can place a watch on each item of the 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); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With