Considérons ce Plnkr par exemple. Je ne sais pas combien de membres de fooCollection
seront créés auparavant. Donc, je ne sais pas combien de modèles bar
vont exister.
Mais je sais qu'ils vont être des modèles angulaires et je sais où ils vont être.
Comment puis-je faire un $watch
sur ceux-ci?
Je dois le faire car je dois déclencher le comportement lorsqu'un modèle bar
est modifié. Regarder le fooCollection lui-même ne suffit pas, l'écouteur $watch
ne se déclenche pas lorsqu'un bar
est modifié.
Html pertinent:
<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 pertinent:
angular
.module('testApp', [])
.controller('testCtrl', function ($scope) {
$scope.fooCollection = [];
$scope.$watch('fooCollection', function (oldValue, newValue) {
if (newValue != oldValue)
console.log(oldValue, newValue);
});
});
Créer des contrôleurs d’éléments de liste individuels: démo sur 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>
Si votre collection est remplie, vous pouvez placer une montre sur chaque élément du 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);
}
Vous pouvez passer true en tant que troisième argument dans $ watch
$scope.$watch('something', function() { doSomething(); }, true);
Vous pouvez également créer une directive personnalisée qui informera votre contrôleur principal des modifications.
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"
};
}]);
suppose que votre balisage est comme ça
<ul>
<li ng-repeat="h in complicatedArrayOfObjects">
<input type="text" ng-model="someModel" batch-watch="$index" />
</li>
</ul>
et ceci est votre contrôleur
YourModule.controller("yourController",[$scope,function($scope){
this.updateChange = function(newVal,oldVal,indexChanged){
console.log("Details about the change");
}
}]);
Vous pouvez également jouer autour de la valeur fournie par la fonction link de la directive qui repose sur les 3 premiers arguments, scope, element et attr.
Comme je ne voulais pas d'un autre contrôleur, j'ai fini par utiliser ng-change .
Simple jsFiddle: https://jsfiddle.net/maistho/z0xazw5n/
HTML pertinent:
<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 pertinent:
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);
};
});
Essayez de faire ça
<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>
Il y a le code dans la directive/contrôleur
$scope.selectedfoo = {};
$scope.select = (foo) => {
$scope.selectedfoo = foo;
}
$scope.$watch('selectedfoo ', (newVal, oldVal) => {
if (newVal) {
}
},true)