How to subscribe on property change when using controller as
syntax?
controller(\'TestCtrl\', function ($
you can actually pass in a function as the first argument of a $watch():
app.controller('TestCtrl', function ($scope) {
this.name = 'Max';
// hmmm, a function
$scope.$watch(function () {}, function (value){ console.log(value) });
});
Which means we can return our this.name reference:
app.controller('TestCtrl', function ($scope) {
this.name = 'Max';
// boom
$scope.$watch(angular.bind(this, function () {
return this.name; // `this` IS the `this` above!!
}), function (value) {
console.log(value);
});
});
Read an interesting post about controllerAs topic https://toddmotto.com/digging-into-angulars-controller-as-syntax/
Writing a $watch in ES6 syntax wasn't as easy as I expected. Here's what you can do:
// Assuming
// controllerAs: "ctrl"
// or
// ng-controller="MyCtrl as ctrl"
export class MyCtrl {
constructor ($scope) {
'ngInject';
this.foo = 10;
// Option 1
$scope.$watch('ctrl.foo', this.watchChanges());
// Option 2
$scope.$watch(() => this.foo, this.watchChanges());
}
watchChanges() {
return (newValue, oldValue) => {
console.log('new', newValue);
}
}
}
You can use:
$scope.$watch("test.name",function(value){
console.log(value)
});
This is working JSFiddle with your example.
Here is how you do this without $scope (and $watch!) Top 5 Mistakes - Abusing watch
If you are using "controller as" syntax, it's better and cleaner to avoid using $scope.
Here is my code in JSFiddle. (I am using a service to hold the name, otherwise the ES5 Object.defineProperty's set and get methods cause infinite calls.
var app = angular.module('my-module', []);
app.factory('testService', function() {
var name = 'Max';
var getName = function() {
return name;
}
var setName = function(val) {
name = val;
}
return {getName:getName, setName:setName};
});
app.controller('TestCtrl', function (testService) {
var vm = this;
vm.changeName = function () {
vm.name = new Date();
}
Object.defineProperty(this, "name", {
enumerable: true,
configurable: false,
get: function() {
return testService.getName();
},
set: function (val) {
testService.setName(val);
console.log(vm.name);
}
});
});