javascriptangularjsangularjs-scopeng-controller

Angularjs: 'controller as syntax' and $watch


How to subscribe on property change when using controller as syntax?

controller('TestCtrl', function ($scope) {
  this.name = 'Max';
  this.changeName = function () {
    this.name = new Date();
  }
  // not working       
  $scope.$watch("name",function(value){
    console.log(value)
  });
});
<div ng-controller="TestCtrl as test">
  <input type="text" ng-model="test.name" />
  <a ng-click="test.changeName()" href="#">Change Name</a>
</div>  

Solution

  • Just bind the relevant context.

    $scope.$watch(angular.bind(this, function () {
      return this.name;
    }), function (newVal) {
      console.log('Name changed to ' + newVal);
    });
    

    Example: http://jsbin.com/yinadoce/1/edit

    UPDATE:

    Bogdan Gersak's answer is actually kind of equivalent, both answers try binding this with the right context. However, I found his answer cleaner.

    Having that said, first and foremost, you have to understand the underlying idea behind it.

    UPDATE 2:

    For those who use ES6, by using arrow function you get a function with the right context OOTB.

    $scope.$watch(() => this.name, function (newVal) {
      console.log('Name changed to ' + newVal);
    });
    

    Example