Question

Considérer ce Plnkr Par exemple.Je ne sais pas combien de membres fooCollection sera créé au préalable.Donc je ne sais pas combien bar des modèles vont exister.

Mais je sais que ce seront des modèles angulaires, et je sais où ils seront.

Comment puis-je faire un $watch sur ceux-ci ?

Je dois le faire parce que je dois déclencher un comportement lorsqu'un bar le modèle est modifié.Regarder fooCollection lui-même ne suffit pas, le $watch l'écouteur ne se déclenche pas lorsqu'un bar est changé.

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);
  });
});
Était-ce utile?

La solution

Créez des contrôleurs d'éléments de liste individuels : démo sur 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>

Autres conseils

Si votre collection est remplie, vous pouvez placer une surveillance 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 comme troisième argument dans $watch

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

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

Vous pouvez également créer une directive personnalisée qui indiquera à votre contrôleur principal les 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"
};
}]);

supposez 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 voici 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 avec la valeur fournie par la fonction de lien de directive qui repose sur les 3 premiers arguments, scope, element et attr.

Comme je ne voulais pas d'autre contrôleur, j'ai fini par utiliser ng-changement plutôt.

JsFiddle simple : 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 Directive/Contrôleur

 $scope.selectedfoo = {};
 $scope.select = (foo) => {
    $scope.selectedfoo = foo;
 }

 $scope.$watch('selectedfoo ', (newVal, oldVal) => {
  if (newVal) {

  }
 },true)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top