AngularJS $watch not working properly

Viewed 311

Recently I am learning Angularjs, my code seems not work as expected: this is my div:

<div ng-app="myApp">
<div ng-controller="myController">
<input type="text" ng-model="data.name" value=""/>
{{data.count}}
</div>
</div>

my controller is:

<script>
var app = angular.module('myApp',[]);
app.controller('myController', function($scope) {

    $scope.data = {
        name:"tom",
        count = 0
    }

    $scope.$watch('data', function(oldValue,newValue) {
        ++$scope.data.count;
    },true);

})
</script>

what I expect is when I type something in the <input> box, the {{data.count}} will increase by 1 each time. However the code is initially 11 and each time I make changes in the input field, the count is increased by 11, can someone help me find where have I done wrong? Thanks a lot in advance.

2 Answers

Why this happen?

Watcher calls multiple times because you created watcher for full object data. Flag true will create sub-watcher for every value in object.

Its a proper behavior. I believe you want something like:

$scope.$watch('data', function(oldValue,newValue) {
         if(oldValue.name != newValue.name){
             ++$scope.data.count;
          }

    },true);

Demo Fiddle


The second solution is to watch on name only:

$scope.$watch(function(){
  return $scope.data.name
  }, function(oldValue,newValue) {
      ++$scope.data.count;
});

Here is a another way to do it. Use the ng-keydown directive and update the count only when a key is pressed inside the input element.

var app = angular.module('myApp', []);
app.controller('MyController', function MyController($scope) {
  $scope.data = {
    name: "tom",
    count: 0
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller='MyController' ng-app='myApp'>
  <input type="text" ng-model="data.name" value="" ng-keydown="data.count = data.count+1" /> {{data.count}}
</div>

Related