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

后端 未结 6 1972
感动是毒
感动是毒 2020-12-08 00:53

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 a

相关标签:
6条回答
  • 2020-12-08 01:07

    Try to do this

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

    There is the code in Directive/Controller

     $scope.selectedfoo = {};
     $scope.select = (foo) => {
        $scope.selectedfoo = foo;
     }
    
     $scope.$watch('selectedfoo ', (newVal, oldVal) => {
      if (newVal) {
    
      }
     },true)
    
    0 讨论(0)
  • 2020-12-08 01:14

    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);
    }
    
    0 讨论(0)
  • 2020-12-08 01:19

    Since I didn't want another controller I ended up using ng-change instead.

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

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

    Relevant 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);
        };
    });
    
    0 讨论(0)
  • 2020-12-08 01:23

    You can pass true as third argument into $watch

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

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

    0 讨论(0)
  • 2020-12-08 01:34

    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>
    
    0 讨论(0)
  • 2020-12-08 01:34

    You can also create a custom directive that will tell your main controller for the changes

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

    assume your markup is like this

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

    and this is your controller

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

    You can also play around the value provided by the directive link function which sits on first 3 arguments, scope,element and attr.

    0 讨论(0)
提交回复
热议问题