$watch not firing on data change $watch not firing on data change angularjs angularjs

$watch not firing on data change


Try passing true as a 3rd argument to .$watch()

$rootScope.Scope documentation

$watch(watchExpression, listener, objectEquality)

objectEquality(optional) – {boolean=} – Compare object for equality rather than for reference.


I fixed some stuff.

http://plnkr.co/edit/5Zaln7QT2gETVcGiMdoW?p=preview

The JS

var myMod = angular.module("myApp",[]).controller("MainController",  function($scope){  $scope.myModel = {selectedId:null};}).controller("DetailController",function($scope){  $scope.items = [1,2,3,4];  $scope.watchHitCount = 0;  $scope.$watch('myModel.selectedId', function(newVal, oldVal){    console.log(newVal + " " + oldVal);    $scope.watchHitCount++;  },true);});

The index.html

  <body ng-app="myApp">    <div ng-controller="MainController">      <ng-include src="'detail.html'" ng-controller="DetailController"></ng-include>    </div>  </body>

The detail.html

<pre>watch hit: {{watchHitCount}}</pre><pre>selected value: {{myModel.selectedId}}</pre><select ng-model="myModel.selectedId" ui-select2="">  <option></option>  <option ng-repeat="item in items" value="{{item}}">{{item}}</option></select>

It was complaining about not finding the controller so I set it up the way I normally would with a named ng-app and a module declared that has controllers defined on it.

I also added an object to hold the value in your model. It is bad practice to use the $scope object as your model, instead your scope should refer to an object that is your model.


There are a simple fix for that, to use watch with complex object instead of simple variable

For example (DON"T USE)

$scope.selectedType=1;//default$scope.$watch(            function () {                return $scope.selectedType;            },            function (newValue, oldValue) {                if (!angular.equals(oldValue, newValue)) {                    $scope.DoWork();                }            },            true);

But Use below

$scope.selecteditem={selectedType:1};$scope.$watch(            function () {                return $scope.selecteditem.selectedType;            },            function (newValue, oldValue) {                if (!angular.equals(oldValue, newValue)) {                    $scope.DoWork();                }            },            true);

note that "slectedTypes" in the second example located inside object, not just scope variable. this will work even in old Angular versions.