it-swarm.com.de

Wie kann man Änderungen an Modellen beobachten, die mit ng-repeat erstellt wurden?

Betrachten Sie diesen Plnkr zum Beispiel. Ich weiß nicht, wie viele Mitglieder von fooCollection vorher erstellt werden. Ich weiß also nicht, wie viele bar Modelle existieren werden.

Aber ich weiß, dass es Winkelmodelle sein werden, und ich weiß, wo sie sich befinden werden.

Wie mache ich einen $watch für diese?

Ich muss das tun, weil ich Verhalten auslösen muss, wenn ein bar-Modell geändert wird. Das Betrachten der fooCollection selbst reicht nicht aus, der $watch-Listener wird nicht ausgelöst, wenn eine bar geändert wird.

Relevante 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>

Relevante JS:

angular
.module('testApp', [])
.controller('testCtrl', function ($scope) {
  $scope.fooCollection = [];

  $scope.$watch('fooCollection', function (oldValue, newValue) {
    if (newValue != oldValue)
      console.log(oldValue, newValue);
  });
});
41
Aditya M P

Erstellen Sie individuelle Listenelement-Controller: Demo auf 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>
34
kapv89

Wenn Ihre Sammlung gefüllt ist, können Sie jedem Element der Wiederholungswiederholung eine Uhr zuordnen:

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);
}
9
Marcel

Sie können true als drittes Argument in $ watch übergeben

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

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

5
v-tec

Sie können auch eine benutzerdefinierte Anweisung erstellen, die Ihren Hauptcontroller über die Änderungen informiert

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"
};
}]);

gehe davon aus, dass dein Markup so ist

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

und das ist dein Controller

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

Sie können auch den Wert verwenden, der von der Direktive-Link-Funktion bereitgestellt wird, die sich auf die ersten drei Argumente, den Gültigkeitsbereich, das Element und das Attribut, setzt.

3
Jomaf

Da ich keinen anderen Controller wollte, habe ich stattdessen ng-change verwendet.

Simple jsFiddle: https://jsfiddle.net/maistho/z0xazw5n/

Relevantes 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>

Relevante 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);
    };
});
2
Maistho

Versuchen Sie das zu tun

 <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>

Es gibt den Code in der Direktive/Controller

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

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

  }
 },true)
0
user2156275