Angularjs: 'controller as syntax' and $watch
Solution 1:
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
Solution 2:
I usually do this:
controller('TestCtrl', function ($scope) {
var self = this;
this.name = 'Max';
this.changeName = function () {
this.name = new Date();
}
$scope.$watch(function () {
return self.name;
},function(value){
console.log(value)
});
});
Solution 3:
You can use:
$scope.$watch("test.name",function(value){
console.log(value)
});
This is working JSFiddle with your example.
Solution 4:
Similar to using the "test" from "TestCtrl as test", as described in another answer, you can assign "self" your scope:
controller('TestCtrl', function($scope){
var self = this;
$scope.self = self;
self.name = 'max';
self.changeName = function(){
self.name = new Date();
}
$scope.$watch("self.name",function(value){
console.log(value)
});
})
In this way, you are not tied to the name specified in the DOM ("TestCtrl as test") and you also avoid the need to .bind(this) to a function.
...for use with the original html specified:
<div ng-controller="TestCtrl as test">
<input type="text" ng-model="test.name" />
<a ng-click="test.changeName()" href="#">Change Name</a>
</div>
Solution 5:
AngularJs 1.5 supports the default $ctrl for the ControllerAs structure.
$scope.$watch("$ctrl.name", (value) => {
console.log(value)
});