Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to $watch changes on models created by ng-repeat?

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);   }); }); 
like image 416
Aditya M P Avatar asked Nov 16 '13 21:11

Aditya M P


People also ask

Does ng-repeat create a new scope?

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.

How do I filter in NG-repeat?

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.

What can I use instead of NG-repeat?

You can consider using transclusion inside a custom directive, to achieve the behavior you are looking for without using ng-repeat.

What does ng-repeat do?

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.


2 Answers

Create individual list-item controllers: demo on 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> 
like image 58
kapv89 Avatar answered Oct 27 '22 00:10

kapv89


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); } 
like image 31
Marcel Avatar answered Oct 26 '22 23:10

Marcel